#include <bits/stdc++.h>
using namespace std;
struct edge{
int a, b, c;
} M[30010];
int n, m, k, q, Euler[30010], lvl[30010], first[15010], Rmq[30010][16], p[15010], dp[15][15010], c[15][15010];
bool u[15010];
vector <pair<int,int> > v[15010];
int pp;
#define dim 100000
char buff[dim];
void read(int &nr){
nr = 0;
while (buff[pp] < '0' || buff[pp] > '9')
if (++pp == dim) fread(buff, 1, dim, stdin), pp = 0;
while (buff[pp]>='0' && buff[pp]<='9'){
nr = nr*10 + buff[pp] - '0';
if (++pp == dim) fread(buff, 1, dim, stdin), pp = 0;
}
}
bool cmp(edge a, edge b){
return a.c < b.c;
}
int find(int i){
if (i == p[i]) return i;
p[i] = find(p[i]);
return p[i];
}
void dfs(int q, int lv){
u[q] = 1;
Euler[++k] = q;
first[q] = k;
lvl[k] = lv;
for (auto it: v[q]){
if (!u[it.first]){
dfs(it.first, lv + 1);
dp[0][it.first] = q;
c[0][it.first] = it.second;
Euler[++k] = q;
lvl[k] = lv;
}
}
}
int lca(int st, int dr){
int l = dr - st + 1, put = 0;
while ( (1<<(put + 1)) <= l) put++;
if (lvl[Rmq[st][put]] < lvl[Rmq[st + l - (1<<put)][put]]) return Euler[Rmq[st][put]];
else return Euler[Rmq[st + l - (1<<put)][put]];
}
int get(int nod, int dist){
if (!dist) return 0;
int put = 0;
while ((1<<(put+1)) <= dist) put++;
return max(c[put][nod], get(dp[put] [nod], dist - (1<<put)));
}
void build(){
//al 2^j-lea stramosi
for (int i=1; (1<<i) <= n; i++){
for (int j=1; j<=n; j++){
dp[i][j] = dp[i-1][dp[i-1][j]];
c[i][j] = max(c[i-1][j], c[i-1][dp[i-1][j]]);
}
}
//costul maxim in ultimii 2^j-lea stramosi ai lui i
}
int main(){
freopen("radiatie.in", "r", stdin);
freopen("radiatie.out", "w", stdout);
read(n); read(m); read(q);
for (int i=1; i<=m; i++){
int x, y, z;
read(x); read(y); read(z);
M[i] = {x, y, z};
}
sort(M+1, M+1+m, cmp);
for (int i=1; i<=n; i++) p[i] = i;
for (int i=1; i<=m && k < n - 1; i++){
int a = find(M[i].a), b = find(M[i].b);
if (a != b){
p[a] = b;
v[M[i].a].push_back({M[i].b, M[i].c});
v[M[i].b].push_back({M[i].a, M[i].c});
k++;
}
}
k = 0;
for (int i=1; i<=n; i++) p[i] = 0;
dfs(1, 1);
build();
//preprocesare pt rmq
for (int i=1; i<=k; i++) Rmq[i][0] = i;
for (int j=1; (1<<j) <= k; j++){
for (int i=1; i + (1<<j) <= k; i++){
if (lvl[Rmq[i][j-1]] < lvl[Rmq[i + (1<<(j-1))][j-1]]) Rmq[i][j] = Rmq[i][j-1];
else Rmq[i][j] = Rmq[i + (1<<(j-1))][j-1];
}
}
for (int i=1; i<=q; i++){
int x, y;
read(x); read(y);
if (first[x] > first[y]) swap(x, y);
int sf = lca(first[x], first[y]);
int left = get(x, lvl[x] - lvl[sf]);
int right = get(y, lvl[y] - lvl[sf]);
cout << max(left, right) << "\n";
}
return 0;
}