#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 1e3;
const int maxm = 3e5 + 1e3;
const long long inf = 1e17 + 10;
int id[maxn], cnt;
long long dis[maxn];
int vis[maxn];
int use[maxn];
struct node {
  int to, pre, iid;
  long long cost;
} e[maxn * 8];
struct Point {
  int v;
  long long cost;
  Point(int _v, long long _c = 0) : v(_v), cost(_c) {}
  bool operator<(const Point& r) const { return cost > r.cost; }
};
void init() {
  memset(id, -1, sizeof(id));
  memset(vis, 0, sizeof(vis));
  memset(use, -1, sizeof(use));
  cnt = 0;
}
void add(int from, int to, int iid, long long cost) {
  e[cnt].to = to;
  e[cnt].cost = cost;
  e[cnt].pre = id[from];
  e[cnt].iid = iid;
  id[from] = cnt++;
}
int n;
void Dijkstra(int now) {
  for (int i = 1; i <= n; ++i) {
    dis[i] = inf;
  }
  dis[now] = 0;
  priority_queue<Point> q;
  q.push(Point(now, 0));
  while (q.size()) {
    Point tmp = q.top();
    q.pop();
    int now = tmp.v;
    if (vis[now])
      continue;
    else
      vis[now] = 1;
    for (int i = id[now]; ~i; i = e[i].pre) {
      int to = e[i].to;
      long long cost = e[i].cost;
      if (!vis[to]) {
        if (dis[to] > dis[now] + cost) {
          dis[to] = dis[now] + cost;
          use[to] = e[i].iid;
          q.push(Point(to, dis[to]));
        } else if (dis[to] == dis[now] + cost) {
          if (e[i].iid == 0) use[to] = e[i].iid;
        }
      }
    }
  }
}
int main() {
  int m, k;
  scanf("%d%d%d", &n, &m, &k);
  init();
  int from, to;
  long long cost;
  for (int i = 1; i <= m; ++i) {
    scanf("%d %d %lld", &from, &to, &cost);
    add(from, to, 0, cost);
    add(to, from, 0, cost);
  }
  from = 1;
  int ans = 0;
  for (int i = 1; i <= k; ++i) {
    scanf("%d %lld", &to, &cost);
    add(from, to, 1, cost);
    add(to, from, 1, cost);
  }
  Dijkstra(1);
  for (int i = 1; i <= n; ++i) {
    if (use[i] == 1) ++ans;
  }
  printf("%d\n", k - ans);
  return 0;
}
