#include <algorithm>
#include <climits>
#include <cstdlib>
#include <iostream>
#include <numeric>
#include <utility>
#include <vector>

struct krawedz {
	int poczatek {};
	int koniec {};
	int waga {};
};

struct krawedz_skierowana {
	int koniec {};
	int waga {};
};

struct wierzcholek_drzewa {
	int glebokosc {};
	std::vector<krawedz_skierowana> przodkowie;
};

class struktura_zbiorow_rozlacznych {
public:
	struktura_zbiorow_rozlacznych(int n)
		: rodzice(n), rzedy(n) {
		std::iota(rodzice.begin(), rodzice.end(), 0);
	}
	int znajdz(int indeks) {
		int& p = rodzice[indeks];
		if (p != indeks)
			p = znajdz(p);
		return p;
	}
	bool polacz(int lhs, int rhs) {
		const int lhs_korzen = znajdz(lhs);
		const int rhs_korzen = znajdz(rhs);
		if (lhs_korzen == rhs_korzen)
			return false;
		int& lhs_rzad = rzedy[lhs_korzen];
		const int rhs_rzad = rzedy[rhs_korzen];
		if (lhs_rzad < rhs_rzad) {
			rodzice[lhs_korzen] = rhs_korzen;
		} else {
			rodzice[rhs_korzen] = lhs_korzen;
			if (lhs_rzad == rhs_rzad)
				lhs_rzad++;
		}
		return true;
	}
private:
	std::vector<int> rodzice;
	std::vector<int> rzedy;
};

bool porownaj_wagi(const krawedz& lhs, const krawedz& rhs) {
	return lhs.waga < rhs.waga;
}

int main() {
	int n, k, q;
	std::cin >> n >> k >> q;
	std::vector<krawedz> krawedzie(k);
	for (int i = 0; i < k; i++) {
		krawedz& kraw = krawedzie[i];
		std::cin >> kraw.poczatek >> kraw.koniec >> kraw.waga;
		kraw.poczatek--;
		kraw.koniec--;
	}
	std::sort(krawedzie.rbegin(), krawedzie.rend(), porownaj_wagi);
	struktura_zbiorow_rozlacznych las(n);
	std::vector<std::vector<krawedz_skierowana>> drzewo_rozpinajace(n);
	for (int i = 0; i < k; i++) {
		const krawedz& kraw = krawedzie[i];
		if (las.polacz(kraw.poczatek, kraw.koniec)) {
			drzewo_rozpinajace[kraw.poczatek].push_back({kraw.koniec, kraw.waga});
			drzewo_rozpinajace[kraw.koniec].push_back({kraw.poczatek, kraw.waga});
		}
	}
	std::vector<wierzcholek_drzewa> drzewo_ukorzenione(n);
	std::vector<bool> odwiedzono(n);
	std::vector<int> stos {0};
	while (!stos.empty()) {
		int wierzcholek = stos.back();
		stos.pop_back();
		odwiedzono[wierzcholek] = true;
		int liczba_krawedzi = drzewo_rozpinajace[wierzcholek].size();
		for (int i = 0; i < liczba_krawedzi; i++) {
			const krawedz_skierowana& kraw = drzewo_rozpinajace[wierzcholek][i];
			if (!odwiedzono[kraw.koniec]) {
				stos.push_back(kraw.koniec);
				wierzcholek_drzewa& dziecko = drzewo_ukorzenione[kraw.koniec];
				dziecko.glebokosc = drzewo_ukorzenione[wierzcholek].glebokosc + 1;
				dziecko.przodkowie.push_back({wierzcholek, kraw.waga});
				for (std::size_t j = 0; 
					j < drzewo_ukorzenione[dziecko.przodkowie[j].koniec].przodkowie.size(); j++) {
					krawedz_skierowana nowa_kraw 
						= drzewo_ukorzenione[dziecko.przodkowie[j].koniec].przodkowie[j];
					nowa_kraw.waga = std::min(nowa_kraw.waga, dziecko.przodkowie[j].waga);
					dziecko.przodkowie.push_back(nowa_kraw);
				}
			}
		}
	}
	for (int i = 0; i < q; i++) {
		int a, b;
		std::cin >> a >> b;
		a--;
		b--;
		if (drzewo_ukorzenione[a].glebokosc < drzewo_ukorzenione[b].glebokosc)
			std::swap(a, b);
		int roznica_glebokosci = drzewo_ukorzenione[a].glebokosc - drzewo_ukorzenione[b].glebokosc;
		int wynik = INT_MAX;
		for (int j = 0; 1 << j <= roznica_glebokosci; j++) {
			if (roznica_glebokosci & 1 << j) {
				wynik = std::min(wynik, drzewo_ukorzenione[a].przodkowie[j].waga);
				a = drzewo_ukorzenione[a].przodkowie[j].koniec;
			}
		}
		while (a != b) {
			int skok = drzewo_ukorzenione[a].przodkowie.size() - 1;
			while (skok > 0 && drzewo_ukorzenione[a].przodkowie[skok].koniec 
				== drzewo_ukorzenione[b].przodkowie[skok].koniec) {
				skok--;
			}
			wynik = std::min(wynik, drzewo_ukorzenione[a].przodkowie[skok].waga);
			a = drzewo_ukorzenione[a].przodkowie[skok].koniec;
			wynik = std::min(wynik, drzewo_ukorzenione[b].przodkowie[skok].waga);
			b = drzewo_ukorzenione[b].przodkowie[skok].koniec;
		}
		std::cout << wynik << '\n';
	}
	return 0;
}
