#include <cstdio>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
const int N_MAX = 15000;
const int logN = 15;
const int aIntSize = 1 << logN;
const int INF = 0x3f3f3f3f;
int n,m,k;
vector< pair<int,int> > G[N_MAX];
vector< pair<int,int> > APM[N_MAX];
typedef vector< pair<int,int> >::iterator EdgeIt;
int aInt[aIntSize+1];
int level[N_MAX];
int str[N_MAX][logN];
int mmax[N_MAX][logN];
vector<int> stack;
void aint_insert ( int cur, int st, int en, int x, int w ) {
if (st == x && x == en) {
aInt[cur] = w;
return;
}
int m = st + (en-st)/2;
if (x <= m) aint_insert(cur*2,st,m,x,w);
if (x > m) aint_insert(cur*2+1,m+1,en,x,w);
aInt[cur] = max(aInt[cur*2],aInt[cur*2+1]);
}
int aint_query ( int cur, int st, int en, int ist, int ien ) {
if (ist <= st && en <= ien)
return aInt[cur];
int m = st + (en-st)/2;
int r1 = -INF, r2 = -INF;
if (ist <= m) r1 = aint_query(cur*2,st,m,ist,ien);
if (ien > m) r2 = aint_query(cur*2+1,m+1,en,ist,ien);
return max(r1,r2);
}
void df ( int k, int in_weight ) {
level[k] = stack.size();
stack.push_back(k);
if (k) aint_insert(1,1,n,level[k],in_weight);
for (int i = 0; (1 << i) <= level[k]; ++i) {
str[k][i] = stack[level[k] - (1 << i)];
mmax[k][i] = aint_query(1,1,n,level[k] - (1 << i) + 1, level[k]);
}
for (EdgeIt i = APM[k].begin(); i != APM[k].end(); ++i) {
if (level[i->first] == -1) {
df(i->first,i->second);
}
}
stack.pop_back();
}
void precalc() {
for (int i = 0; i < n; ++i) level[i] = -1;
for (int i = 0; i < n; ++i)
for (int j = 0; j < logN; ++j)
mmax[i][j] = -INF;
for (int i = 0; i <= aIntSize; ++i) aInt[i] = -INF;
df(0,-1);
}
int trace ( int &nod, int d ) {
int m = -INF;
for (int i = 0; (1 << i) <= d; ++i) {
if ((1 << i) & d) {
m = max(m,mmax[nod][i]);
d -= (1 << i);
nod = str[nod][i];
}
}
return m;
}
int solve ( int x, int y ) {
if (x == y) return 0;
if (level[x] > level[y]) x ^= y ^= x ^= y;
int m = trace(y,level[y]-level[x]), lvl = level[x];
int step;
for (step = 1; (1 << (step + 1)) <= lvl; ++step);
for (; step >= 0; --step) {
if (str[x][step] != str[y][step]) {
m = max(m,mmax[x][step]);
x = str[x][step];
m = max(m,mmax[y][step]);
y = str[y][step];
}
}
if (x != y) {
m = max(m,mmax[x][0]);
m = max(m,mmax[y][0]);
x = str[x][0];
y = str[y][0];
}
return m;
}
int dist[N_MAX];
class dcmp {
public:
bool operator() ( const int &a, const int &b ) { return dist[a] < dist[b]; };
};
struct FullEdge {
int a,b,v;
};
void get_apm ( vector< pair<int,int> > G[], int n, vector< pair<int,int> > A[] ) {
set<int,dcmp> S;
vector<FullEdge> vei(n);
vector<bool> used(n);
set<int,dcmp>::iterator cur = S.begin();
dist[0] = 0;
used[0] = true;
for (int i = 1; i < n; ++i) dist[i] = 0x3f3f3f3f;
for (S.insert(0); !S.empty(); ) {
cur = S.begin();
if (*cur != 0) {
used[*cur] = true;
A[vei[*cur].a].push_back(make_pair(vei[*cur].b, vei[*cur].v));
A[vei[*cur].b].push_back(make_pair(vei[*cur].a, vei[*cur].v));
}
for (EdgeIt i = G[*cur].begin(); i != G[*cur].end(); ++i) {
if (dist[i->first] > i->second && !used[i->first]) {
set<int,dcmp>::iterator loc = S.find(i->first);
if (loc != S.end())
S.erase(loc);
dist[i->first] = i->second;
vei[i->first].a = *cur;
vei[i->first].b = i->first;
vei[i->first].v = i->second;
S.insert(i->first);
}
}
S.erase(cur);
}
}
int main() {
freopen("radiatie.in","rt",stdin);
freopen("radiatie.out","wt",stdout);
scanf("%d %d %d",&n,&m,&k);
for (int i = 0, a,b,v; i < m; ++i) {
scanf("%d %d %d",&a,&b,&v);
--a; --b;
G[a].push_back(make_pair(b,v));
G[b].push_back(make_pair(a,v));
}
get_apm(G,n,APM);
precalc();
for (int i = 0, a,b; i < k; ++i) {
scanf("%d %d",&a,&b);
--a; --b;
printf("%d\n",solve(a,b));
}
return 0;
}