#include <bits/stdc++.h>
using namespace std;
const int Max = 201000;
const long long inf = 1e15 + 1;
long long dis[Max], n, m, k;
struct edge {
  int u, s;
  long long val;
};
struct ed {
  int i;
  long long val;
  ed(int a = 0, long long b = 0) {
    i = a;
    val = b;
  }
};
vector<edge> G[Max];
struct com {
  bool operator()(ed a, ed b) { return a.val > b.val; }
};
priority_queue<ed, vector<ed>, com> que;
int visit[Max];
int train[Max];
void input() {
  int a, b, c;
  edge e;
  for (int i = 0; i < m; i++) {
    e.s = 0;
    scanf("%d%d%d", &a, &b, &c);
    e.u = b;
    e.val = c;
    G[a].push_back(e);
    e.u = a;
    G[b].push_back(e);
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &b, &c);
    e.u = b;
    e.val = c;
    e.s = 1;
    G[1].push_back(e);
  }
}
void dijkstra() {
  fill(dis, dis + n + 1, inf);
  dis[1] = 0;
  memset(visit, 0, sizeof(visit));
  memset(train, 0, sizeof(train));
  que.push(ed(1, 0));
  train[1] = 0;
  while (!que.empty()) {
    ed u = que.top();
    que.pop();
    if (visit[u.i]) continue;
    visit[u.i] = 1;
    for (int j = 0; j < (int)G[u.i].size(); j++) {
      int v = G[u.i][j].u;
      if (!visit[v]) {
        if (dis[v] > u.val + G[u.i][j].val) {
          dis[v] = u.val + G[u.i][j].val;
          train[G[u.i][j].u] = G[u.i][j].s;
          que.push(ed(v, dis[v]));
        } else if (dis[v] == u.val + G[u.i][j].val) {
          if (G[u.i][j].s == 0) train[G[u.i][j].u] = 0;
        }
      }
    }
  }
}
int main() {
  cin >> n >> m >> k;
  input();
  dijkstra();
  int ans = k;
  for (int i = 1; i <= n; i++)
    if (train[i]) ans--;
  cout << ans << endl;
  return 0;
}
