#include <bits/stdc++.h>
using namespace std;
const int N_MAX = 15001, LOG_N = 15, M_MAX = 30001;
int N, M, K, logN;
int timer;
int tin[2 * N_MAX], tout[2 * N_MAX];
int up[N_MAX][LOG_N];
int maxUp[N_MAX][LOG_N];
struct FixedEdge
{
int v1, v2, c;
inline bool operator< (const FixedEdge& rhs) const
{
return c < rhs.c;
}
};
struct Edge
{
int v, c;
Edge(int _v, int _c) :
v(_v), c(_c) { }
};
FixedEdge Edges[M_MAX];
vector<Edge> G[N_MAX];
struct DisjointSetUnion
{
int T[N_MAX];
int Size[N_MAX];
int N;
inline void MakeSet(int& v)
{
T[v] = v;
Size[v] = 1;
}
int FindSet(int v)
{
if(T[v] != v)
T[v] = FindSet(T[v]);
return T[v];
}
bool AreDisjoint(int a, int b)
{
return FindSet(a) != FindSet(b);
}
void Union(int a, int b)
{
a = FindSet(a);
b = FindSet(b);
if(a == b)
return;
if(Size[a] < Size[b])
swap(a, b);
T[b] = a;
Size[a] += Size[b];
}
void Build(int N)
{
this->N = N;
for(int i = 1; i <= N; i++)
MakeSet(i);
}
} dsu;
void SetInput(string name)
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
(void)!freopen((name + ".in").c_str(), "r", stdin);
(void)!freopen((name + ".out").c_str(), "w", stdout);
}
void ReadInput()
{
cin >> N >> M >> K;
for(int i = 0; i < M; i++)
cin >> Edges[i].v1 >> Edges[i].v2 >> Edges[i].c;
}
void Kruskal()
{
sort(Edges, Edges + M);
for(int i = 0; i < M; i++)
{
auto [v1, v2, c] = Edges[i];
if(dsu.AreDisjoint(v1, v2))
{
dsu.Union(v1, v2);
G[v1].emplace_back(v2, c);
G[v2].emplace_back(v1, c);
}
}
}
void DFS(int v, int p)
{
tin[v] = ++timer;
up[v][0] = p;
for(int i = 1; i <= logN; i++)
{
up[v][i] = up[up[v][i-1]][i-1];
maxUp[v][i] = max(maxUp[v][i-1], maxUp[up[v][i-1]][i-1]);
}
for(auto& [u, cost] : G[v])
if(u != p)
{
maxUp[u][0] = cost;
DFS(u, v);
}
tout[v] = ++timer;
}
inline bool IsAncestor(int& u, int& v)
{
return tin[u] <= tin[v] && tout[u] >= tout[v];
}
int LCA(int u, int v)
{
if(IsAncestor(u, v))
return u;
if(IsAncestor(v, u))
return v;
for(int i = logN; i >= 0; i--)
if(not IsAncestor(up[u][i], v))
u = up[u][i];
return up[u][0];
}
void BuildLCA()
{
timer = 0;
logN = ceil(log2(N));
maxUp[1][0] = 0;
DFS(1, 1);
}
int FindMaxInPath(int v, int p)
{
if(v == p)
return 0;
if(not IsAncestor(p, v))
return 0;
int ans = 0;
for(int i = logN; i >= 0; i--)
if(not IsAncestor(up[v][i], p))
{
ans = max(ans, maxUp[v][i]);
v = up[v][i];
}
ans = max(ans, maxUp[v][0]);
return ans;
}
void AnswerQueries()
{
for(int i = 0, u, v, lca, ans; i < K; i++)
{
cin >> u >> v;
lca = LCA(u, v);
ans = FindMaxInPath(u, lca);
ans = max(ans, FindMaxInPath(v, lca));
cout << ans << '\n';
}
}
int main()
{
SetInput("radiatie");
ReadInput();
dsu.Build(N);
Kruskal();
BuildLCA();
AnswerQueries();
return 0;
}