#include <bits/stdc++.h>
using namespace std;
const long long INF = (long long)1000000000 * (long long)1000000000;
const long long MOD = 1e9 + 7;
const int MAXN = 200010;
struct EDGE {
  int v, id;
  long long d;
  EDGE(int v_, int id_, long long d_) : v(v_), id(id_), d(d_) {}
};
std::vector<EDGE> e[MAXN];
long long dist[2][MAXN];
int u[MAXN], v[MAXN], w[MAXN];
bool usedEdge[MAXN];
int pre[MAXN];
int pos[MAXN];
int L[MAXN], R[MAXN];
void AddEdge(int x, int y, long long d, int id) {
  e[x].push_back(EDGE(y, id, d));
}
bool vis[MAXN];
int qq[MAXN], top;
void SPFA(int s, int n, long long dis[]) {
  for (int i = 1; i <= n; i++) {
    dis[i] = INF;
    vis[i] = false;
    pre[i] = -1;
  }
  dis[s] = 0;
  vis[s] = true;
  top = 0;
  int front = 0;
  int rear = 0;
  qq[rear++] = s;
  while (front != rear) {
    s = qq[front++];
    if (front == MAXN) front = 0;
    vis[s] = false;
    for (int i = 0; i < e[s].size(); i++) {
      int v = e[s][i].v;
      long long tmp = dis[s] + e[s][i].d;
      if (tmp < dis[v]) {
        dis[v] = tmp;
        pre[v] = e[s][i].id;
        if (!vis[v]) {
          vis[v] = true;
          qq[rear++] = v;
          if (rear == MAXN) rear = 0;
        }
      }
    }
  }
}
int ExtractMainPath(int n, int m) {
  memset(usedEdge, false, sizeof(bool) * (m + 5));
  memset(pos, -1, sizeof(int) * (n + 5));
  int size = 0;
  int cur = 1;
  while (pre[cur] != -1) {
    pos[cur] = size++;
    int id = pre[cur];
    usedEdge[id] = true;
    if (u[id] == cur) {
      cur = v[id];
    } else {
      cur = u[id];
    }
  }
  pos[cur] = size++;
  return size;
}
struct Query {
  int qid, l, r;
  long long minDis;
  Query() {}
  Query(int qid_, int l_, int r_, long long minDis_)
      : qid(qid_), l(l_), r(r_), minDis(minDis_) {}
} q[MAXN];
struct Interval {
  int l, r;
  long long val;
  Interval() {}
  Interval(int l_, int r_, long long val_) : l(l_), r(r_), val(val_) {}
} interval[MAXN << 1];
long long ans[MAXN];
std::vector<int> dir[MAXN];
int dgr[MAXN];
std::set<pair<int, int> > connectExist;
void AddConnect(int a, int b) {
  std::pair<int, int> p = make_pair(a, b);
  if (connectExist.find(p) != connectExist.end()) {
    return;
  }
  connectExist.insert(p);
  dir[a].push_back(b);
  dgr[b]++;
}
void CalcBoundry(int n, long long disL[], long long disR[], int b[], int m,
                 int sign, long long minDis, int initB) {
  connectExist.clear();
  for (int i = 1; i <= n; i++) {
    dir[i].clear();
    dgr[i] = 0;
  }
  for (int i = 1; i <= m; i++) {
    if (usedEdge[i]) {
      continue;
    }
    if (disL[u[i]] + w[i] == disL[v[i]]) {
      AddConnect(u[i], v[i]);
    }
    if (disL[v[i]] + w[i] == disL[u[i]]) {
      AddConnect(v[i], u[i]);
    }
  }
  top = 0;
  for (int i = 1; i <= n; i++) {
    if (pos[i] > -1) {
      b[i] = pos[i];
    } else {
      b[i] = initB;
    }
  }
  for (int i = 1; i <= n; i++) {
    if (dgr[i] == 0) {
      qq[top++] = i;
    }
  }
  while (top > 0) {
    top--;
    int s = qq[top];
    for (int i = 0; i < dir[s].size(); i++) {
      int v = dir[s][i];
      if ((b[s] - b[v]) * sign < 0) {
        b[v] = b[s];
      }
      dgr[v]--;
      if (dgr[v] == 0) {
        qq[top++] = v;
      }
    }
  }
}
bool QueryCmp(const Query& a, const Query& b) { return a.r < b.r; }
bool IntervalCmp(const Interval& a, const Interval& b) { return a.r < b.r; }
long long tree[MAXN];
long long query(int t) {
  long long ret = INF;
  while (t) {
    ret = min(ret, tree[t]);
    t -= (-t) & t;
  }
  return ret;
}
void ins(int t, long long v, int n) {
  while (t <= n) {
    tree[t] = min(v, tree[t]);
    t += (-t) & t;
  }
}
int main() {
  int n, m, Q;
  cin >> n >> m >> Q;
  for (int i = 1; i <= n; i++) {
    e[i].clear();
  }
  for (int i = 1; i <= m; i++) {
    scanf("%d%d%d", &u[i], &v[i], &w[i]);
    AddEdge(u[i], v[i], w[i], i);
    AddEdge(v[i], u[i], w[i], i);
  }
  SPFA(1, n, dist[0]);
  SPFA(n, n, dist[1]);
  long long minDis = dist[0][n];
  int treeSize = ExtractMainPath(n, m);
  CalcBoundry(n, dist[0], dist[1], L, m, 1, minDis, treeSize + 1);
  CalcBoundry(n, dist[1], dist[0], R, m, -1, minDis, -1);
  int intervalSize = 0;
  for (int i = 1; i <= m; i++) {
    if (usedEdge[i]) {
      continue;
    }
    long long disU2V = dist[0][u[i]] + dist[1][v[i]] + w[i];
    interval[intervalSize++] = Interval(L[u[i]], R[v[i]], disU2V);
    long long disV2U = dist[0][v[i]] + dist[1][u[i]] + w[i];
    interval[intervalSize++] = Interval(L[v[i]], R[u[i]], disV2U);
  }
  for (int i = 1; i <= Q; i++) {
    int t, x;
    scanf("%d%d", &t, &x);
    long long d =
        min(dist[0][u[t]] + dist[1][v[t]], dist[0][v[t]] + dist[1][u[t]]) + x;
    int l = -1, r = -1;
    if (usedEdge[t]) {
      l = pos[u[t]];
      r = pos[v[t]];
      if (l > r) {
        std::swap(l, r);
      }
    }
    q[i] = Query(i, l, r, d);
  }
  sort(q + 1, q + Q + 1, QueryCmp);
  sort(interval, interval + intervalSize, IntervalCmp);
  for (int i = 1; i <= treeSize; i++) {
    tree[i] = INF;
  }
  int curQ = Q, curI = intervalSize - 1;
  for (; curQ >= 1; curQ--) {
    while (curI >= 0 && interval[curI].r >= q[curQ].r) {
      ins(interval[curI].l + 1, interval[curI].val, treeSize);
      curI--;
    }
    if (q[curQ].l == -1) {
      ans[q[curQ].qid] = min(q[curQ].minDis, minDis);
    } else {
      ans[q[curQ].qid] = min(q[curQ].minDis, query(q[curQ].l + 1));
    }
  }
  for (int i = 1; i <= Q; i++) {
    printf("%I64d\n", ans[i]);
  }
  return 0;
}
