#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cassert>
using namespace std;
typedef long long ll;

#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define FOREQ(i, k, n) for (int i = (k); i <= (int)(n); ++i)
#define FORIT(i, c) for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

#define SZ(v) (int)((v).size())
#define MEMSET(v, h) memset((v), (h), sizeof(v))
#define FIND(m, w) ((m).find(w) != (m).end())

typedef int Weight;
struct Edge {
  int index;
  int src;
  int dest;
  Weight weight;
  Edge(int index, int src, int dest, Weight weight) : index(index), src(src), dest(dest), weight(weight) {;}
  bool operator<(const Edge &rhs) const {
    if (weight != rhs.weight) { return weight > rhs.weight; }
    if (src != rhs.src) { return src < rhs.src; }
    return dest < rhs.dest;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void PrintMatrix(const Matrix &matrix) {
  for (int y = 0; y < (int)matrix.size(); y++) {
    for (int x = 0; x < (int)matrix[y].size(); x++) {
      printf("%d ", matrix[y][x]);
    }
    puts("");
  }
}

Weight augment(const Graph &g, Array &capacity, const vector<int> &level, vector<bool> &finished, int from, int t, Weight cur) {
  if (from == t || cur == 0) { return cur; }
  if (finished[from]) { return 0; }
  for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
    int to = it->dest;
    if (level[to] != level[from] + 1) { continue; }
    Weight f = augment(g, capacity, level, finished, to, t, min(cur, capacity[it->index]));
    if (f > 0) {
      capacity[it->index] -= f;
      capacity[it->index^1] += f;
      return f;
    }
  }
  finished[from] = true;
  return 0;
}

// index^1 is reverse edge
Weight MaxFlow(const Graph &g, int e, int s, int t) {
  int n = g.size();
  Array capacity(e);
  for (int from = 0; from < n; from++) {
    for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
      capacity[it->index] += it->weight;
    }
  }
  int ans = 0;
  while (true) {
    vector<int> level(n, -1);
    level[s] = 0;
    queue<int> que;
    que.push(s);
    for (int d = n; !que.empty() && level[que.front()] < d; ) {
      int from = que.front();
      que.pop();
      if (from == t) { d = level[from]; }
      for (Edges::const_iterator it = g[from].begin(); it != g[from].end(); it++) {
        int to = it->dest;
        if (capacity[it->index] > 0 && level[to] == -1) {
          que.push(to);
          level[to] = level[from] + 1;
        }
      }
    }
    vector<bool> finished(n);
    bool end = true;
    while (true) {
      Weight f = augment(g, capacity, level, finished, s, t, 2000000000LL);
      if (f == 0) { break; }
      ans += f;
      end = false;
    }
    if (end) { break; }
  }
  return ans;
}


void addEdge(int &e, Graph &g, int from, int to) {
    g[from].push_back(Edge(e++, from, to, 1));
    g[to].push_back(Edge(e++, to, from, 0));
}

int n, m, l;
inline int IN(int x) { return 2 * x; }
inline int OUT(int x) { return 2 * x + 1; }
inline int SOURCE() { return 2 * l; }
inline int DEST() { return 2 * l + 1; }
inline int SIZE() { return 2 * l + 2; }

ll matrix[110][110];
int point[1010];
ll ontime[1010];
bool visit[2020];

int main() {
    while (scanf("%d %d %d", &n, &m, &l), n|m|l) {
      int e = 0;
        MEMSET(matrix, 0x0f);
        Graph g(2 * l + 2);
        REP(i, m) {
            int f, t, c;
            scanf("%d %d %d", &f, &t, &c);
            matrix[f][t] = min(matrix[f][t], (ll)c);
            matrix[t][f] = min(matrix[t][f], (ll)c);
        }
        REP(k, n) REP(i, n) REP(j, n) {
            matrix[j][j] = 0;
            matrix[i][j] = min(matrix[i][j], matrix[i][k] + matrix[k][j]);
        }
        REP(i, l) {
            int p, t;
            scanf("%d %d", &p, &t);
            point[i] = p;
            ontime[i] = t;
        }
        REP(i, l) {
            addEdge(e, g, SOURCE(), IN(i));
            addEdge(e, g, OUT(i), DEST());
            REP(j, l) {
              if(i == j) { continue; }
                if (ontime[j] + matrix[point[j]][point[i]] <= ontime[i]) {
                    addEdge(e, g, IN(i), OUT(j));
                }
            }
        }
        printf("%d\n", l - MaxFlow(g, e, SOURCE(), DEST()));
    }
}

Measured memory_bytes: 24000