//
//  main.cpp
//

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2251

#include <algorithm>
#include <array>
#include <assert.h>
#include <iostream>
#include <limits>
#include <math.h>
#include <memory>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = long long;
using ull = unsigned long long;

namespace Util {
    int bipartite_match(size_t, size_t, const function<bool(size_t, size_t)>&);
    int min_path_cover_dag(size_t, const function<bool(size_t, size_t)>&);
    int clamp_sum(int, int);
};

struct Network {
    struct Edge {
        size_t to; // 行き先
        int cap; // 容量
        size_t rev; // 逆辺インデックス
        Edge(size_t to, int cap, size_t rev): to(to), cap(cap), rev(rev) {};
    };
    vector<vector<Edge>> graph; // グラフの隣接リスト表現
    // コンストラクタ
    explicit Network(size_t vertices) {
        graph.resize(vertices);
    }
    // 辺を追加する
    void add_edge(size_t from, size_t to, int cap) {
        assert(from < graph.size() && to < graph.size());
        graph[from].emplace_back(to, cap, graph[to].size());
        graph[to].emplace_back(from, 0, graph[from].size() - 1);
    }
    // Ford-Fulkerson法で最大流を求める
    int max_flow_ff(size_t s, size_t t) {
        assert(s < graph.size() && t < graph.size());
        int max_flow = 0;
        while (true) {
            vector<bool> used(graph.size(), false);
            int flow = dfs_path(s, t, numeric_limits<int>::max(), used);
            if (flow == 0) {
                return max_flow;
            }
            max_flow += flow;
        }
    }
    // 始点vから終点tへのパスをDFSで見つけて水を流す。流した分だけ各辺のcapacityが変化する。
    // return 流した流量
    // max_flow 見つけたパスに流す流量の最大値。それ以上は（流せても）流さない。
    // used 訪問済み頂点フラグ
    int dfs_path(size_t v, size_t t, int max_flow, vector<bool>& used) {
        assert(used.size() == graph.size());
        assert(v < graph.size() && t < graph.size());
        if (v == t) {
            return max_flow;
        }
        used[v] = true;
        for (Edge& e : graph[v]) {
            if (used[e.to] || e.cap == 0) { // 行き先が訪問済みか、これ以上流せない辺なら
                continue;
            }
            int flow = dfs_path(e.to, t, min(e.cap, max_flow), used);
            if (flow == 0) {
                continue;
            }
            e.cap -= flow;
            graph[e.to][e.rev].cap += flow;
            return flow;
        }
        return 0;
    }
};

// 重み付き有効グラフ、隣接行列表現
struct MatrixCostGraph {
    // cost[i][j] = iからjへのコスト、接続されていない場合はintのmax。対角線は0。
    vector<vector<int>> cost;
    // コンストラクタ
    MatrixCostGraph(size_t vertices) {
        cost = vector<vector<int>>(vertices, vector<int>(vertices, numeric_limits<int>::max()));
        for (size_t v = 0; v < vertices; v++) {
            cost[v][v] = 0;
        }
    }
    // エッジを追加する（単方向）
    void set_edge(size_t from, size_t to, int edge_cost) {
        cost[from][to] = edge_cost;
    }
    // エッジを追加する（双方向）
    void set_edge_bidir(size_t from, size_t to, int edge_cost) {
        cost[from][to] = edge_cost;
        cost[to][from] = edge_cost;
    }
    // ワーシャルフロイド法で全点対最短路を求める
    // O(N^3)
    vector<vector<int>> warshall_floyd() const {
        vector<vector<int>> ret = cost;
        for (int k = 0; k < cost.size(); k++) {
            for (int i = 0; i < cost.size(); i++) {
                for (int j = 0; j < cost.size(); j++) {
                    // ret[i][j]に頂点i,j,[0..k]までを使う場合の最短路を求める
                    ret[i][j] = min(ret[i][j], Util::clamp_sum(ret[i][k], ret[k][j]));
                }
            }
        }
        return ret;
    }
};

namespace Util {
    // 二部グラフの最大マッチングを求める
    int bipartite_match(size_t u_size, size_t v_size, const function<bool(size_t, size_t)>& is_connected) {
        Network net(u_size + v_size + 2); // 0=start, 1=end, uたち, vたち
        const size_t U_START = 2;
        const size_t V_START = U_START + u_size;
        for (size_t u = 0; u < u_size; u++) {
            net.add_edge(0, u + U_START, 1);
        }
        for (size_t v = 0; v < v_size; v++) {
            net.add_edge(v + V_START, 1, 1);
        }
        for (size_t u = 0; u < u_size; u++) {
            for (size_t v = 0; v < v_size; v++) {
                if (is_connected(u, v)) {
                    net.add_edge(u + U_START, v + V_START, 1);
                }
            }
        }
        return net.max_flow_ff(0, 1);
    }
    // DAGに対して最小パスカバーを求める
    int min_path_cover_dag(size_t vertices, const function<bool(size_t, size_t)>& has_edge) {
        assert(vertices <= numeric_limits<int>::max());
        return (int)vertices - Util::bipartite_match(vertices, vertices,
                                                     [vertices, &has_edge](size_t u, size_t v) -> bool {
                                                         assert(v < vertices && u < vertices);
                                                         return has_edge(u, v);
                                                     });
    }
    int clamp_sum(int x, int y) {
        return (int)min((ll)numeric_limits<int>::max(), max((ll)numeric_limits<int>::min(), (ll)x + (ll)y));
    }
}

int main() {
    int N, M, L;
    while (true) {
        cin >> N >> M >> L;
        if (N == 0 && M == 0 && L == 0) {
            return 0;
        }
        MatrixCostGraph roads(N);
        for (int i = 0; i < M; i++) {
            int u, v, d;
            cin >> u >> v >> d;
            roads.set_edge_bidir(u, v, d);
        }
        vector<vector<int>> dists = roads.warshall_floyd();
        struct Request {
            int house_idx;
            int time;
        };
        vector<Request> reqs;
        for (int i = 0; i < L; i++) {
            int house_idx, time;
            cin >> house_idx >> time;
            reqs.push_back((Request){house_idx, time});
        }
        auto has_edge = [&dists, &reqs](size_t u, size_t v) -> bool {
            int time = reqs[v].time - reqs[u].time;
            if (time <= 0) {
                return false;
            }
            int dist = dists[reqs[u].house_idx][reqs[v].house_idx];
            return dist <= time;
        };
//#ifdef DEBUG
//        for (size_t u = 0; u < L; u++) {
//            for (size_t v = 0; v < L; v++) {
//                cout << "[" << u << "," << v << "]=" << has_edge(u, v) << endl;
//            }
//        }
//#endif
        int min_santas = Util::min_path_cover_dag(L, has_edge);
        cout << min_santas << endl;
    }
}

/*
 
 10 10 10
 0 1 39
 2 3 48
 3 5 20
 4 8 43
 3 9 10
 8 9 40
 3 4 5
 5 7 20
 1 7 93
 1 3 20
 0 0
 1 100000000
 2 100
 3 543
 4 500
 5 400
 6 300
 7 200
 8 100
 9 100
 
 10 10 9
 0 1 39
 2 3 48
 3 5 20
 4 8 43
 3 9 10
 8 9 40
 3 4 5
 5 7 20
 1 7 93
 1 3 20
 0 0
 2 100
 3 543
 4 500
 5 400
 6 300
 7 200
 8 100
 9 100
 
 */



Measured memory_bytes: 32728