#include "bits/stdc++.h"
using namespace std;
#ifdef _DEBUG
#include "dump.hpp"
#else
#define dump(...)
#endif

//#define int long long
#define rep(i,a,b) for(int i=(a);i<(b);i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)
const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)(1e9) + 7;
template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

struct BipartiteMatching {
	int n;
	vector<vector<int>> g;
	vector<int> match;
	vector<int> used;
	BipartiteMatching(int n) : n(n), g(n), match(n), used(n) {}
	void addEdge(int u, int v) {
		g[u].emplace_back(v);
		g[v].emplace_back(u);
	}
	int maximumMatching() {
		int cnt = 0;
		rep(i, 0, n)match[i] = -1;
		for (int v = 0; v < n; v++) {
			if (match[v] == -1) {
				rep(i, 0, n)used[i] = false;
				if (augment(v))cnt++;
			}
		}
		return cnt;
	}
	bool augment(int v) {
		used[v] = true;
		for (int u : g[v]) {
			int w = match[u];
			if (w == -1 || (!used[w] && augment(w))) {
				match[v] = u;
				match[u] = v;
				return true;
			}
		}
		return false;
	}
};

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	for (int N, M, L; cin >> N >> M >> L&&N;) {
		vector<vector<int>> g(N, vector<int>(N, INF));
		rep(i, 0, M) {
			int u, v, d; cin >> u >> v >> d;
			g[u][v] = g[v][u] = d;
		}
		rep(i, 0, N)
			g[i][i] = 0;
		rep(k, 0, N)rep(i, 0, N)rep(j, 0, N) {
			if (g[i][k] != INF&&g[k][j] != INF)
				g[i][j] = min(g[i][j], g[i][k] + g[k][j]);
		}

		vector<int> p(L), t(L); rep(i, 0, L) {
			cin >> p[i] >> t[i];
		}
		BipartiteMatching bm(L + L);
		int source = L + L, sink = source + 1;
		rep(i, 0, L) {
			rep(j, 0, L) {
				if (i == j)continue;
				if (g[p[i]][p[j]] <= t[j] - t[i]) {
					bm.addEdge(i, L + j);
				}
			}
		}
		auto ans = L - bm.maximumMatching();
		cout << ans << endl;
	}
	return 0;
}