#include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
#include <queue>

#define show(x) cerr << #x << " = " << x << endl
using namespace std;
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v)
{
    os << "sz:" << v.size() << "\n[";
    for (const auto& p : v) {
        os << p << ",";
    }
    os << "]\n";
    return os;
}

using ll = long long;
template <typename T>
constexpr T INF = numeric_limits<T>::max() / 8;

struct CostGraph {
    using T = ll;
    CostGraph(const int v) : V{v}
    {
        edge.resize(v);
        rev_edge.resize(v);
    }
    struct Edge {
        Edge(const int from, const int to, const T cost) : from{from}, to{to}, cost{cost} {}
        const int from;
        const int to;
        const T cost;
        bool operator<(const Edge& e) const
        {
            return cost != e.cost ? cost < e.cost : to < e.to;
        }
    };
    void addEdge(const int from, const int to, const T cost)
    {
        edge[from].push_back(Edge{from, to, cost});
        rev_edge[to].push_back(Edge(to, from, cost));
    }
    vector<vector<Edge>> edge;
    vector<vector<Edge>> rev_edge;
    const int V;
};

void WarshallFloyd(const CostGraph& g, vector<vector<CostGraph::T>>& d)
{
    using T = CostGraph::T;
    assert(d.size() == g.V);
    for (int i = 0; i < g.V; i++) {
        assert(d[i].size() == g.V);
        for (int j = 0; j < g.V; j++) {
            if (i == j) {
                d[i][j] = 0;
            } else {
                d[i][j] = INF<T>;
            }
        }
        for (const auto& e : g.edge[i]) {
            d[i][e.to] = min(e.cost, d[i][e.to]);  // For doubled-link
        }
    }
    for (int k = 0; k < g.V; k++) {
        for (int i = 0; i < g.V; i++) {
            for (int j = 0; j < g.V; j++) {
                if (d[i][j] > d[i][k] + d[k][j] and d[i][k] < INF<T> and d[k][j] < INF<T>) {
                    d[i][j] = d[i][k] + d[k][j];
                }
            }
        }
    }
}

class Flow
{
public:
    using T = ll;
    struct Edge {
        Edge(const int from_, const int to_, const int reverse_, const T capacity_, bool is_reverse = false) : from{from_}, to{to_}, reverse{reverse_}, capacity{capacity_}, flow{0}, is_reverse(is_reverse) {}
        int from;
        int to;
        int reverse;
        T capacity;
        T flow;
        bool is_reverse;
    };

    Flow(const int v) : V{v}
    {
        edge.resize(v);
    }
    void addEdge(const int from, const int to, const T capacity)
    {
        edge[from].push_back(Edge{from, to, (int)edge[to].size(), capacity, false});
        edge[to].push_back(Edge{to, from, (int)edge[from].size() - 1, 0, true});
    }

    T FordFulkerson(const int s, const int t)
    {
        vector<bool> checked(V);
        T flow = 0;
        while (true) {
            for (int i = 0; i < V; i++) {
                checked[i] = false;
            }
            const T f = dfs_ff(s, t, INF<T>, checked);
            if (f == 0) {
                break;
            }
            flow += f;
        }
        return flow;
    }

    T Dinic(const int s, const int t)
    {
        T flow = 0;
        while (true) {
            vector<int> level(V, -1);
            queue<int> q;
            q.push(s);
            level[s] = 0;
            while (not q.empty()) {
                const int v = q.front();
                for (const auto& e : edge[s]) {
                    if (e.capacity > e.flow and level[e.to] < 0) {
                        level[e.to] = level[v] + 1;
                        q.push(e.to);
                    }
                }
            }
            while (true) {
                const T f = dfs_dinic(s, t, INF<T>, level);
                if (f == 0) {
                    break;
                }
                flow += f;
            }
        }
    }

    const int V;
    vector<vector<Edge>> edge;

private:
    T dfs_ff(const int pos, const int t, const T flow, vector<bool>& checked)
    {
        if (pos == t) {
            return flow;
        }
        checked[pos] = true;
        for (auto& e : edge[pos]) {
            if (not checked[e.to]) {
                const T res = e.capacity - e.flow;
                if (res > 0) {
                    const T d = dfs_ff(e.to, t, min(flow, res), checked);
                    if (d > 0) {
                        e.flow += min(d, res);
                        edge[e.to][e.reverse].flow -= min(d, res);
                        return d;
                    }
                }
            }
        }
        return 0;
    }

    T dfs_dinic(const int pos, const int t, const T flow, const vector<int>& level)
    {
        if (pos == t) {
            return flow;
        }
        for (auto& e : edge[pos]) {
            const T res = e.capacity - e.flow;
            if (res > 0 and level[pos] < level[e.to]) {
                const T d = dfs_dinic(e.to, t, min(flow, res), level);
                if (d > 0) {
                    e.flow += min(d, res);
                    edge[e.to][e.reverse].flow -= min(d, res);
                    return d;
                }
            }
        }
        return 0;
    }
};

int main()
{
    while (true) {
        int N, M, L;
        cin >> N >> M >> L;
        if (N == 0 and M == 0 and L == 0) {
            break;
        }
        CostGraph g(N);
        for (int i = 0; i < M; i++) {
            int u, v;
            ll d;
            cin >> u >> v >> d;
            g.addEdge(u, v, d);
            g.addEdge(v, u, d);
        }
        vector<vector<ll>> d(N, vector<ll>(N, INF<ll>));
        WarshallFloyd(g, d);
        using P = pair<int, ll>;
        vector<P> req(L);
        for (int i = 0; i < L; i++) {
            int p;
            ll t;
            cin >> p >> t;
            req[i] = {p, t};
        }

        Flow flow(2 * L + 2);
        const int S = 2 * L;
        const int T = 2 * L + 1;
        for (int i = 0; i < L; i++) {
            flow.addEdge(S, i, 1);
            flow.addEdge(i + L, T, 1);
            for (int j = 0; j < L; j++) {
                if (i == j) {
                    continue;
                }
                const int p1 = req[i].first;
                const ll t1 = req[i].second;
                const int p2 = req[j].first;
                const ll t2 = req[j].second;
                if (t1 < t2) {
                    if (d[p1][p2] <= t2 - t1) {
                        flow.addEdge(i, j + L, 1);
                    }
                }
            }
        }
        cout << L - flow.FordFulkerson(S, T) << endl;
    }
    return 0;
}



Measured memory_bytes: 50268