#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 210, INF = 1e9;
int n, m, Q;
int d[N][N];
//从任意的i到任意的j,最短路径有两种情况
//1、i直接到j
//2、i经过若干的点到j
//即式子d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
//一眼看去,感觉只是多考虑的一个点k,i->k,k->j是不是比i->j短,但展开看就发现,其实是考虑了1到k-1的节点总和
//有4个点,1,2,3,4;当k=3 d[1][4] = min(d[1][4], d[1][3] + d[3][4]),
//d[1][3]可能是d[1][2] + d[2][3], d[1][4] = min(d[1][4], d[1][2] + d[2][3] + d[3][4])
//例子只供理解思路,不是真实例子。
void floyd()
{
for(int k = 1; k <= n; k ++)
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
int main()
{
scanf("%d%d%d", &n, &m, &Q);
//初始化
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
if(i == j) d[i][j] = 0;
else d[i][j] = INF;
while(m --)
{
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
d[a][b] = min(d[a][b], w);
}
floyd();
while(Q --)
{
int a, b;
scanf("%d%d", &a, &b);
int t = d[a][b];
if(t > INF / 2) puts("impossible");
else printf("%d\n", t);
}
return 0;
}