#include <bits/stdc++.h>
using namespace std;
const int N = 15005;
const int lgN = 15;
vector < int > v[N];
vector < pair < int, int > > Q[N];
int normalized[N];
int root[N], fs[N], sn[N], ans[N], euler[2*N], aint[8*N], dfsV[N], cost[N], lg2[N];
int dp[N];
int rmq[N][lgN];
int qlf, qrg, all;
const int INF = 1<<30;
struct thing{
int x, y, c;
}edge[2 * N];
bool comp(thing a, thing b){
return a.c < b.c;
}
int getRoot(int x){
if(root[x] != x){
return root[x] = getRoot(root[x]);
}
return root[x];
}
void unite(int x, int y){
x = getRoot(x);
y = getRoot(y);
root[y] = x;
}
void eulerTour(int node, int parent){
int rn = normalized[node];
euler[++all] = rn;
fs[rn] = all;
for(auto it : v[node]){
if(it != parent){
eulerTour(it, node);
euler[++all] = rn;
}
}
sn[rn] = all;
}
void build(int pos, int lf, int rg){
if(lf == rg){
aint[pos] = euler[lf];
return;
}
int md = (lf + rg)/2;
build(2 * pos, lf, md);
build(2 * pos + 1, md + 1, rg);
aint[pos] = min(aint[2 * pos], aint[2 * pos + 1]);
}
int query(int pos, int lf, int rg){
if(lf > qrg || rg < qlf){
return INF;
}
if(qlf <= lf && rg <= qrg){
return aint[pos];
}
int md = (lf + rg)/2;
return min( query(2 * pos, lf, md), query(2 * pos + 1, md + 1, rg) );
}
int getMax(int x, int y){
if(x < y){
return -INF;
}
int lg = lg2[x - y + 1];
return max(rmq[dfsV[x]][lg], rmq[dfsV[y + (1<<lg) - 1]][lg]);
}
void dfs(int node, int parent, int depth){
int rn = normalized[node];
dfsV[depth] = rn;
dp[rn] = depth;
rmq[rn][0] = cost[node];
for(int j = 1;(1<<j) <= depth;j++){
rmq[rn][j] = max(rmq[rn][j - 1], rmq[dfsV[depth - (1<<(j - 1))]][j - 1]);
}
for(auto it : Q[rn]){
ans[it.second] = max(ans[it.second], getMax(dp[rn], dp[it.first] + 1));
}
for(auto it : v[node]){
if(it != parent){
dfs(it, node, depth + 1);
}
}
}
int cnt;
bool used[2*N];
int p[N];
void liniarize(int node, int parent){
cnt++;
p[node] = parent;
normalized[node] = cnt;
for(auto it : v[node]){
if(it != parent){
liniarize(it, node);
}
}
}
int main(){
int n,m,q,i,j;
freopen("radiatie.in", "r", stdin);
freopen("radiatie.out", "w", stdout);
scanf("%d %d %d", &n, &m, &q);
for(i = 1;i <= n;i++){
root[i] = i;
for(j = 1;j < lgN;j++){
rmq[i][j] = -INF;
}
}
lg2[2] = 1;
for(i = 3;i <= N;i++){
lg2[i] = lg2[i >> 1] + 1;
}
for(i = 1;i <= m;i++){
int x, y, c;
scanf("%d %d %d", &x, &y, &c);
edge[i] = {x, y, c};
}
sort(edge + 1, edge + m + 1, comp);
cost[1] = -INF;
for(i = 1;i <= m;i++){
int x, y;
x = edge[i].x;
y = edge[i].y;
if(getRoot(x) != getRoot(y)){
v[x].push_back(y);
v[y].push_back(x);
used[i] = 1;
unite(x, y);
}
}
liniarize(1, 0);
for(i = 1;i <= m;i++){
if(used[i]){
int x, y;
x = edge[i].x;
y = edge[i].y;
if(p[y] == x){
cost[y] = edge[i].c;
}else{
cost[x] = edge[i].c;
}
}
}
eulerTour(1, 0);
build(1, 1, all);
for(i = 1;i <= q;i++){
ans[i] = -INF;
int x, y;
scanf("%d %d", &x, &y);
x = normalized[x];
y = normalized[y];
if(fs[x] > sn[y]){
swap(x, y);
}
qlf = fs[x];
qrg = sn[y];
int LCA = query(1, 1, all);
Q[x].push_back({LCA, i});
Q[y].push_back({LCA, i});
}
dfs(1, 0, 1);
for(i = 1;i <= q;i++){
printf("%d\n", ans[i]);
}
return 0;
}