#include "bits/stdc++.h"
using namespace std;
template <typename... T> void read(T& ... t){ ((cin >> t), ...); }
template <typename... T> void write(T ... t){ ((cout << t), ...); }
//#define int long long
#define FAST ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define size(x) (int)x.size()
#define all(x) x.begin(),x.end()
#define endl '\n'
#define FOR(i,a,b) for(int i=a; i<=b; ++i)
#define ROF(i,b,a) for(int i=b; i>=a; --i)
using LL = long long;
using pii = pair<int,int>;
const int INF = 2e9;
const int MAX_N = 2e4 +3;

struct Dsu {
	vector<int> _leader, _size;
	Dsu(int _n) {
		_leader.assign(_n+1,0);
		_size.assign(_n+1,0);
		FOR(i,1,_n){ _leader[i] = i; _size[i] = 1; }
	}
	int leader(int x) { return (_leader[x]==x) ? x : _leader[x]=leader(_leader[x]); }
	void unite(int x, int y) {
		x = leader(x);
		y = leader(y);
		if(x == y) return;
		_leader[y] = x;
		_size[x] += _size[y];
	}
};
template<typename T> struct SparseT{
	int n,lg;
	vector<vector<T>> arr;
	T neutral;
	function<T(T, T)> Combine;
	function<int(int, int)> Nxt;
	function<bool(int, int)>  HasNxt;
	SparseT(){}
	SparseT(int _n, T _neutral, function<T(T,T)>_combine,function<int(int,int)>_nxt,function<int(int,int)> _hasNxt){
		n = _n;
		lg = log2(_n);
		neutral = _neutral;
		arr.assign(lg+1, vector<T>(n+1, neutral));
		Combine = _combine;
		Nxt = _nxt;
		HasNxt = _hasNxt;
	}
	T& base(int node){
		return arr[0][node];
	}
	T get(int node, int len){
		T ans = neutral;
		while(len > 0){
			int jump = __builtin_ctz(len);
			len -= (1<<jump);
			ans = Combine(ans, arr[jump][node]);
			node = Nxt(node, jump);
		}
		return ans;
	}
	void computeAll(){
		for(int jump=1; jump<=lg; ++jump) for(int node=1; node<=n; ++node) if(HasNxt(node,jump)){
			int nxt = Nxt(node, jump-1);
			arr[jump][node] = Combine(arr[jump-1][node], arr[jump-1][nxt]);
		}
	}
};

int n,m,q;
vector<tuple<int,int,int>> e;
vector<pii> adj[MAX_N];
int dep[MAX_N];

SparseT<int> parent, minW;

Dsu dsu(MAX_N);

void explore(int u, int prv, int prvW, int depth){
	parent.base(u) = prv;
	minW.base(u) = prvW;
	dep[u] = depth;
	for(auto &[v,w]: adj[u]) if(v != prv) explore(v, u, w, depth+1);
}

int lca(int x, int y) {
    if (dep[y] > dep[x]) swap(x, y);
    int diff = dep[x] - dep[y];
    ROF(jump,parent.lg,0) if(diff&(1<<jump)) x = parent.arr[jump][x];
      
	if (x == y) return x;
      
	ROF(jump,parent.lg,0) if(parent.arr[jump][x] != parent.arr[jump][y]) {
        x = parent.arr[jump][x]; 
		y = parent.arr[jump][y];
    }
    return parent.arr[0][x];
}

int32_t main(){ FAST;
	read(n,m,q);
	FOR(mm,1,m){
		int u,v,w; read(u,v,w);
		e.emplace_back(u,v,w);
	}

	sort(all(e), [&](auto &a, auto &b){ return get<2>(a) > get<2>(b); });

	for(auto &[u,v,w]: e){
		if(dsu.leader(u) == dsu.leader(v)) continue;
		dsu.unite(u, v);
		adj[u].emplace_back(v,w);
		adj[v].emplace_back(u,w);
	}

	parent = SparseT<int>(n,0,
	[&](int old,int cur){return cur;},
	[&](int node,int jump){return parent.arr[jump][node];},
	[&](int node,int jump){return dep[node] >= (1<<jump);});
	minW = SparseT<int>(n,INF,
	[&](int old,int cur){return min(old,cur);},
	[&](int node,int jump){return parent.arr[jump][node];},
	[&](int node,int jump){return dep[node] >= (1<<jump);});

	explore(1, 1, INF, 1);

	parent.computeAll();
	minW.computeAll();

	FOR(qq,1,q){
		int u,v; read(u,v);
		int p = lca(u, v);
		int w1 = minW.get(u, dep[u]-dep[p]);
		int w2 = minW.get(v, dep[v]-dep[p]);
		write(min(w1, w2), endl);
	}
}