#include <bits/stdc++.h>
using namespace std;
vector<int> res;
const long long inf = 1e17;
struct node {
  int v, nxt;
  long long w;
  int flag;
} edge[2000005];
struct nd {
  int p;
  long long d;
  nd() {}
  nd(long long _d, int _to) : d(_d), p(_to) {}
  bool operator<(const nd &a) const { return d > a.d; }
};
int tot, n, m, nn, used[1000005], head[1000005];
long long da[1000005];
int ff[1000005];
void add(int u, int v, long long w, int ff) {
  edge[tot].v = v;
  edge[tot].w = w;
  edge[tot].flag = ff;
  edge[tot].nxt = head[u];
  head[u] = tot++;
}
int cc = 0;
struct cmp {
  bool operator()(const pair<int, nd> &x, const pair<int, nd> &y) {
    if (x.second.d != y.second.d) return x.second.d > y.second.d;
    return x.first > y.first;
  }
};
void Dijkstra(int s, long long d[]) {
  priority_queue<pair<int, nd>, vector<pair<int, nd> >, cmp> que;
  while (!que.empty()) que.pop();
  memset(used, 0, sizeof(used));
  d[s] = 0;
  que.push(pair<int, nd>(0, nd(d[s], s)));
  while (!que.empty()) {
    pair<int, nd> top = que.top();
    que.pop();
    int u = top.second.p;
    if (used[u]) continue;
    used[u] = 1;
    if (top.first == 1) cc++;
    for (int k = head[u]; ~k; k = edge[k].nxt) {
      int v = edge[k].v;
      if (used[v]) continue;
      int w = edge[k].w;
      int train = edge[k].flag;
      if (d[u] + w <= d[v]) {
        d[v] = d[u] + w;
        que.push(pair<int, nd>(train, nd(d[v], v)));
      }
    }
  }
}
long long db[1000005];
long long len[1000005];
int main() {
  int k;
  scanf("%d %d %d", &nn, &m, &k);
  memset(head, -1, sizeof(head));
  for (int i = 1; i <= m; i++) {
    int a, b;
    long long c;
    scanf("%d%d%lld", &a, &b, &c);
    add(a, b, c, 0);
    add(b, a, c, 0);
  }
  for (int i = 0; i <= nn; i++) da[i] = inf;
  for (int i = 1; i <= k; i++) {
    int a;
    long long c;
    scanf("%d%lld", &a, &c);
    add(1, a, c, 1);
    add(a, 1, c, 1);
  }
  Dijkstra(1, da);
  cout << k - cc << endl;
}
