#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 5;
const int MAXM = 4e5 + 5;
const long long INF = 0x3f3f3f3f3f3f3f3f;
struct Node {
  int to, dist, id;
  Node() = default;
  Node(int x, int y, int z) : to(x), dist(y), id(z) {}
};
struct Node1 {
  int pos;
  long long dist;
  Node1() = default;
  Node1(int x, long long y) : pos(x), dist(y) {}
  inline bool operator<(const Node1 &x) const { return dist > x.dist; }
} x;
vector<Node> v[MAXN];
int n, m, q, xx[MAXN], yy[MAXN], dat[MAXN], pre[MAXN], pre1[MAXN], pre2[MAXN];
int is[MAXN], vis[MAXN], vis1[MAXN], vis2[MAXN], ls[MAXM], rs[MAXM];
int root, tree_cnt, tot, vvis[MAXN];
long long dis[MAXN], dis1[MAXN], dis2[MAXN], lazy[MAXM], ddis[MAXN];
inline int read() {
  int x = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x;
}
template <typename T>
inline void Max(T &x, T y) {
  if (x < y) x = y;
}
template <typename T>
inline void Min(T &x, T y) {
  if (x > y) x = y;
}
inline void prepare() {
  priority_queue<Node1> q;
  memset(dis, 0x3f, sizeof(dis));
  q.push(Node1(n, 0)), dis[n] = 0, vis[1] = 1;
  while (!q.empty()) {
    x = q.top(), q.pop();
    if (vis[x.pos]) continue;
    vis[x.pos] = 1;
    for (auto y : v[x.pos])
      if (dis[y.to] > dis[x.pos] + y.dist) {
        pre[y.to] = x.pos;
        dis[y.to] = dis[x.pos] + y.dist;
        q.push(Node1(y.to, dis[y.to]));
      }
  }
  memset(ddis, 0x3f, sizeof(ddis));
  q.push(Node1(1, 0)), ddis[1] = 0, vvis[n] = 1;
  while (!q.empty()) {
    x = q.top(), q.pop();
    if (vvis[x.pos]) continue;
    vvis[x.pos] = 1;
    for (auto y : v[x.pos])
      if (ddis[y.to] > ddis[x.pos] + y.dist) {
        ddis[y.to] = ddis[x.pos] + y.dist;
        q.push(Node1(y.to, ddis[y.to]));
      }
  }
}
void dfs(int x, int dep) {
  if (x == n) {
    tot = dep;
    return;
  }
  for (auto y : v[x]) {
    if (y.to != pre[x] || ddis[x] + dis[pre[x]] + y.dist != ddis[n]) continue;
    is[y.id] = ++dep;
    dfs(pre[x], dep);
    break;
  }
}
inline void prepare1() {
  priority_queue<Node1> q;
  memset(dis1, 0x3f, sizeof(dis1));
  q.push(Node1(1, 0)), dis1[1] = 0, vis1[n] = 1;
  while (!q.empty()) {
    x = q.top(), q.pop();
    if (vis1[x.pos]) continue;
    vis1[x.pos] = 1;
    for (auto y : v[x.pos]) {
      if (dis1[y.to] == dis1[x.pos] + y.dist)
        Min(pre1[y.to], max(pre1[x.pos], is[y.id]));
      else if (dis1[y.to] > dis1[x.pos] + y.dist) {
        dis1[y.to] = dis1[x.pos] + y.dist;
        q.push(Node1(y.to, dis1[y.to]));
        pre1[y.to] = max(pre1[x.pos], is[y.id]);
      }
    }
  }
}
inline void prepare2() {
  priority_queue<Node1> q;
  memset(dis2, 0x3f, sizeof(dis2));
  memset(pre2, 0x3f, sizeof(pre2));
  q.push(Node1(n, 0)), dis2[n] = 0, pre2[n] = tot + 1, vis2[1] = 1;
  while (!q.empty()) {
    x = q.top(), q.pop();
    if (vis2[x.pos]) continue;
    vis2[x.pos] = 1;
    for (auto y : v[x.pos]) {
      if (dis2[y.to] == dis2[x.pos] + y.dist) {
        Max(pre2[y.to], pre2[x.pos]);
        if (is[y.id]) Min(pre2[y.to], is[y.id]);
      } else if (dis2[y.to] > dis2[x.pos] + y.dist) {
        dis2[y.to] = dis2[x.pos] + y.dist;
        q.push(Node1(y.to, dis2[y.to]));
        pre2[y.to] = pre2[x.pos];
        if (is[y.id]) Min(pre2[y.to], is[y.id]);
      }
    }
  }
}
void build(int l, int r, int &cur) {
  cur = ++tree_cnt;
  lazy[cur] = INF;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(l, mid, ls[cur]);
  build(mid + 1, r, rs[cur]);
}
void modify(int l, int r, int ql, int qr, long long to, int cur) {
  if (ql <= l && qr >= r) {
    Min(lazy[cur], to);
    return;
  }
  int mid = (l + r) >> 1;
  if (ql <= mid) modify(l, mid, ql, qr, to, ls[cur]);
  if (qr > mid) modify(mid + 1, r, ql, qr, to, rs[cur]);
}
inline long long query(int l, int r, int qc, int cur) {
  if (l == r) return lazy[cur];
  int mid = (l + r) >> 1;
  if (qc <= mid)
    return min(lazy[cur], query(l, mid, qc, ls[cur]));
  else
    return min(lazy[cur], query(mid + 1, r, qc, rs[cur]));
}
inline void change() {
  build(1, tot, root);
  for (int i = 1; i <= m; i++) {
    if (is[i]) continue;
    if (pre1[xx[i]] + 1 <= pre2[yy[i]] - 1)
      modify(1, tot, pre1[xx[i]] + 1, pre2[yy[i]] - 1,
             dis1[xx[i]] + dis2[yy[i]] + dat[i], root);
    if (pre1[yy[i]] + 1 <= pre2[xx[i]] - 1)
      modify(1, tot, pre1[yy[i]] + 1, pre2[xx[i]] - 1,
             dis1[yy[i]] + dis2[xx[i]] + dat[i], root);
  }
}
inline void solve() {
  while (q--) {
    int t = read(), x = read();
    if (!is[t]) {
      long long cur =
          min(dis1[xx[t]] + dis2[yy[t]] + x, dis2[xx[t]] + dis1[yy[t]] + x);
      if (x >= dat[t])
        printf("%lld\n", dis1[n]);
      else
        printf("%lld\n", min(dis1[n], cur));
    } else {
      if (x <= dat[t])
        printf("%lld\n", dis1[n] - dat[t] + x);
      else
        printf("%lld\n", min(dis1[n] - dat[t] + x, query(1, tot, is[t], root)));
    }
  }
}
int main() {
  n = read(), m = read(), q = read();
  for (int i = 1; i <= m; i++) {
    xx[i] = read(), yy[i] = read(), dat[i] = read();
    v[xx[i]].push_back(Node(yy[i], dat[i], i));
    v[yy[i]].push_back(Node(xx[i], dat[i], i));
  }
  prepare(), dfs(1, 0);
  prepare1(), prepare2(), change();
  solve();
  return 0;
}
