#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
const ll INF = 1e18;
int n, m, v[N], k, num, ru[N];
ll dis[N];
struct node
{
    ll to;
    ll w;
} now;
struct P
{
    ll u, w;
} p[N];
vector<node> g[N];

void add(int x, int y, ll z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        dis[i] = INF;
    dis[1] = 0;
    ru[1] = 1;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] == dis[x] + now.w)
            {
                ru[now.to]++;
            }
            if (dis[now.to] > dis[x] + now.w)
            {
                ru[now.to] = 1;
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= m; i++)
    {
        ll x, y, z;
        scanf("%lld%lld%lld", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }

    //cout << dis[3] << endl;
    for (int i = 1; i <= k; i++)
    {
        int u, w;
        scanf("%lld%lld", &p[i].u, &p[i].w);
        add(1, p[i].u, p[i].w);
        add(p[i].u, 1, p[i].w);
    }
    solve();
    for (int i = 1; i <= k; i++)
    {
        if (dis[p[i].u] < p[i].w)
            num++;
        else if (dis[p[i].u] == p[i].w && ru[p[i].u] >= 2)
        {
            num++;
            ru[p[i].u]--;
        }
    }
    cout << num << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
const ll INF = 1e15;
int n, m, v[N], k, num;
ll dis[N];
struct node
{
    int to;
    ll w;
} now;
vector<node> g[N];

void add(int x, int y, ll z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i < N; i++)
        dis[i] = INF;
    dis[1] = 0;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] > dis[x] + now.w)
            {
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        ll z;
        scanf("%d%d%lld", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }
    solve();
    //cout << dis[3] << endl;
    for (int i = 1; i <= k; i++)
    {
        int u;
        ll w;
        scanf("%d%lld", &u, &w);
        if (w <= dis[u])
            num++;
    }
    cout << num << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
const ll INF = 1e18;
ll n, m, v[N], k, num, ru[N];
ll dis[N];
struct node
{
    ll to;
    ll w;
} now;
struct P
{
    ll u, w;
} p[N];
vector<node> g[N];

void add(int x, int y, ll z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        dis[i] = INF;
    dis[1] = 0;
    //ru[1] = 1;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        v[x] = 0;
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] == dis[x] + now.w)
            {
                ru[now.to]++;
            }
            if (dis[now.to] > dis[x] + now.w)
            {
                ru[now.to] = 1;
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%lld%lld%lld", &n, &m, &k);
    for (int i = 1; i <= m; i++)
    {
        ll x, y, z;
        scanf("%lld%lld%lld", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }

    //cout << dis[3] << endl;
    for (int i = 1; i <= k; i++)
    {
        int u, w;
        scanf("%lld%lld", &p[i].u, &p[i].w);
        add(1, p[i].u, p[i].w);
        add(p[i].u, 1, p[i].w);
    }
    solve();
    for (int i = 1; i <= k; i++)
    {
        if (dis[p[i].u] < p[i].w)
            num++;
        else if (dis[p[i].u] == p[i].w && ru[p[i].u] >= 2)
        {
            num++;
            ru[p[i].u]--;
        }
    }
    cout << num << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const ll INF = 1e15;
int n, m,v[N],k,num;
ll dis[N];
struct node
{
    int to, w;
} now;
vector<node> g[N];

void add(int x, int y, int z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        dis[i] = INF;
    dis[1] = 0;
    v[1]=1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] > dis[x] + now.w)
            {
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for (int i = 1; i <= n;i++)
    {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }
    solve();
    for (int i = 1; i <= k;i++)
    {
        int u;
        ll w;
        scanf("%d%lld",&u,&w);
        if(w>=dis[u])
            num++;
    }
    cout << num<<endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
const ll INF = 1e15;
int n, m, v[N], k, num;
ll dis[N];
struct node
{
    int to;
    int flag;
    ll w;
} now;
vector<node> g[N];

void add(int x, int y, ll z, int f)
{
    now.to = y;
    now.w = z;
    now.flag = f;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i < N; i++)
        dis[i] = INF;
    dis[1] = 0;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] > dis[x] + now.w)
            {
                if (now.flag == 0)
                    num++;
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= m; i++)
    {
        int x, y;
        ll z;
        scanf("%d%d%lld", &x, &y, &z);
        add(x, y, z, 1);
        add(y, x, z, 1);
    }

    //cout << dis[3] << endl;
    for (int i = 1; i <= k; i++)
    {
        int u;
        ll w;
        scanf("%d%lld", &u, &w);
        add(1, u, w, 0);
        add(u, 1, w, 0);
    }
    solve();
    cout << k - num << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
const ll INF = 1e15;
int n, m, v[N], k, num;
ll dis[N];
struct node
{
    int to;
    ll w;
} now;
vector<node> g[N];

void add(int x, int y, ll z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i < N; i++)
        dis[i] = INF;
    dis[1] = 0;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] > dis[x] + now.w)
            {
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        int x, y;
        ll z;
        scanf("%d%d%lld", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }
    solve();
    //cout << dis[3] << endl;
    for (int i = 1; i <= m; i++)
    {
        int u;
        ll w;
        scanf("%d%lld", &u, &w);
        if (w <= dis[u])
            num++;
    }
    cout << num << endl;
}


#include <iostream>
#include <vector>
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 2e6 + 10;
const ll INF = 1e15;
int n, m, v[N], k, num;
ll dis[N];
struct node
{
    int to, w;
} now;
vector<node> g[N];

void add(int x, int y, int z)
{
    now.to = y;
    now.w = z;
    g[x].push_back(now);
}

void solve()
{
    queue<int> q;
    for (int i = 1; i <= n; i++)
        dis[i] = INF;
    dis[1] = 0;
    v[1] = 1;
    q.push(1);
    while (!q.empty())
    {
        int x = q.front();
        q.pop();
        for (int i = 0; i < g[x].size(); i++)
        {
            now = g[x][i];
            if (dis[now.to] > dis[x] + now.w)
            {
                dis[now.to] = dis[x] + now.w;
                if (!v[now.to])
                {
                    v[now.to] = 1;
                    q.push(now.to);
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d", &n, &m, &k);
    for (int i = 1; i <= n; i++)
    {
        int x, y, z;
        scanf("%d%d%d", &x, &y, &z);
        add(x, y, z);
        add(y, x, z);
    }
    solve();
    for (int i = 1; i <= k; i++)
    {
        int u;
        ll w;
        scanf("%d%lld", &u, &w);
        if (w >= dis[u])
            num++;
    }
    cout << num << endl;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 6;
const ll inf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;
ll dis[MAXN], Y[MAXN];
bool vis[MAXN];
int n, m;
int in[MAXN], X[MAXN];
ll x, y, w, k;
struct node
{
	ll v, w;
	bool operator < (const node& a)const
	{
		return this->w > a.w;
	}
};
vector<node>ve[MAXN];
void Dijkstra(int s)
{
	for (int i = 0; i <= n; i++)
		dis[i] = inf;
	priority_queue<node>que;
	que.push({ s,0 });
	dis[s] = 0;
	while (!que.empty())
	{
		node tmp = que.top();
		que.pop();
		int u = tmp.v;
		if (vis[u])continue;
		vis[u] = true;
		for (int i = 0; i < ve[u].size(); i++)
		{
			int v = ve[u][i].v;
			int cost = ve[u][i].w;
			if (!vis[v])
			{
				if (dis[v] > dis[u] + cost)
				{
					in[v] = 1;
					dis[v] = dis[u] + cost;
					que.push({ v,dis[v] });
				}
				else if (dis[v] == dis[u] + cost)
					in[v]++;
			}
		}
	}
}
int main()
{
	scanf("%d%d%lld", &n, &m, &k);
	for (int i = 0; i < m; i++)
	{
		scanf("%lld%lld%lld", &x, &y, &w);
		ve[x].push_back({ y,w });
		ve[y].push_back({ x,w });
	}
	for (int i = 1; i <= k; i++)
	{
		scanf("%d%lld", &X[i], &Y[i]);
		ve[X[i]].push_back({ 1,Y[i] });
		ve[1].push_back({ X[i],Y[i] });
	}
	ll ans = 0;
	Dijkstra(1);
	for (int i = 1; i <= k; i++)
	{
		if (dis[X[i]] == inf)continue;
		if (dis[X[i]] < Y[i])
			ans++;
		else if (dis[X[i]] == Y[i])
		{
			if (in[X[i]] > 1)
			{
				ans++;
				in[X[i]]--;
			}
		}
	}
	printf("%lld\n", ans);
	return 0;
}


// Jzzhu.cpp : Этот файл содержит функцию "main". Здесь начинается и заканчивается выполнение программы.
//

#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
#define mp make_pair
#define pb push_back
const int M = 100001;

struct edge {
	int x;
	ll cst;
	bool f;
	edge(int a, ll b, bool c) {
		x = a; cst = b; f = c;
	}
	bool operator <(const edge &a)const {
		if (cst == a.cst)
			return f > a.f;
		return cst > a.cst;
	}
};

int n, m, x, y, z, a, b, k, ans;
vector<pair<int, int> >v[M];
bool vis[M];
ll cost[M];
priority_queue<edge>q;

void dijkstra() {
	q.push(edge(1, 0, 0));
	for (int i = 1; i <= n; i++)cost[i] = 1e18;
	cost[1] = 0;
	while (!q.empty()) {
		edge a = q.top();
		q.pop();
		if (vis[a.x]) {
			ans += a.f;
			continue;
		}
		vis[a.x] = true;
		for (int i = 0; i < v[a.x].size(); i++) {
			int newnode = v[a.x][i].first;
			int edgecost = v[a.x][i].second;
			if (edgecost + a.cst < cost[newnode]) {
				cost[newnode] = edgecost + a.cst;
				q.push(edge(newnode, cost[newnode], 0));
			}
		}
	}

}
int main() {

	cin >> n >> m >> k;
	for (int i = 0; i < m; i++) {
		cin >> x >> y >> z;
		v[x].push_back(make_pair(y, z));
		swap(x, y);
		v[x].push_back(make_pair(y, z));
	}
	for (int i = 0; i < k; i++) {
		cin >> x >> y;
		q.push(edge(x, y, 1));
	}
	dijkstra();
	cout << ans;
	return 0;
}


#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define int  long long
#define MAXN 800004
using namespace std;
inline int read ()
{
	int a = 0;
	bool op = 0;
	char c = getchar ();
	while (c < '0' || c>'9')
	{
		if (c == '-')
			op = 1;
		c = getchar ();
	}
	while (c >= '0' && c <= '9')
	{
		a = a * 10 + c - '0';
		c = getchar ();
	}
	return op ? -a : a;
}
struct  edge {
	int to, next, w, op;
}e[MAXN << 1];

int ans = 0, n, m;
int np = 0, first[MAXN << 1];
void add (int u, int v, int w, int op)
{
	e[++np] = {v,first[u],w,op};
	first[u] = np;
}

int dist[MAXN << 1];
struct node {
	int i, d;
	friend bool operator<(node a, node b)
	{
		return dist[a.i] > dist[b.i];
	}
};

void dij ();

pair<int, int>wait[MAXN];
int go[MAXN << 2];

signed main ()
{
	n = read (), m = read ();
	int k = read ();
	for (int i = 1; i <= m; i++)
	{
		int a = read (), b = read (), c = read ();
		add (a, b, c, 0);
		add (b, a, c, 0);
	}
	for (int i = 1; i <= n; i++)
		dist[i] = INF;
	for (int i = 1; i <= k; i++)
	{
		int a = read (), b = read ();
		add (1, a, b, 1);
	}
	ans = k;
	dij ();
	for (int i = 2; i <= n; i++)
	{
		if (e[go[i]].op == 1)
		{
			ans--;
		}
	}
	cout << ans;
	return 0;
}

bool vis[MAXN];
void dij ()
{
	memset (vis, 0, sizeof (vis));
	dist[1] = 0;
	priority_queue<node>q;
	q.push ({1,0});
	while (!q.empty ())
	{
		node tmp = q.top ();
		q.pop ();
		int i = tmp.i;
		if (vis[i])
			continue;
		else
			vis[i] = 1;
		for (int p = first[i]; p; p = e[p].next)
		{
			int j = e[p].to;
			if (dist[i] + e[p].w < dist[j])
			{
				dist[j] = dist[i] + e[p].w;
				q.push ({j,dist[j]});
				go[j] = p;
			}
			else if (dist[i] + e[p].w == dist[j])
			{
				if (e[p].op == 1)
				{
					continue;
				}
				else
				{
					go[j] = p;
				}
			}
		}
	}
}


#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define int long long
#define MAXN 800004
using namespace std;
inline int read ()
{
	int a = 0;
	bool op = 0;
	char c = getchar ();
	while (c < '0' || c>'9')
	{
		if (c == '-')
			op = 1;
		c = getchar ();
	}
	while (c >= '0' && c <= '9')
	{
		a = a * 10 + c - '0';
		c = getchar ();
	}
	return op ? -a : a;
}
struct  edge {
	int to, next, w, op;
}e[MAXN << 1];

int ans = 0, n, m;
int np = 0, first[MAXN << 1];
void add (int u, int v, int w, int op)
{
	e[++np] = {v,first[u],w,op};
	first[u] = np;
}

int dist[MAXN << 1];
struct node {
	int i, d;
	friend bool operator < (node a, node b)
	{
		return a.d > b.d;
	}
};

void dij ();

int go[MAXN << 2];

signed main ()
{
	n = read (), m = read ();
	int k = read ();
	for (int i = 1; i <= m; i++)
	{
		int a = read (), b = read (), c = read ();
		add (a, b, c, 0);
		add (b, a, c, 0);
	}
	for (int i = 1; i <= n; i++)
		dist[i] = INF;
	for (int i = 1; i <= k; i++)
	{
		int a = read (), b = read ();
		add (1, a, b, 1);
	}
	ans = k;
	dij ();
	for (int i = 2; i <= n; i++)
	{
		if (e[go[i]].op == 1)
		{
			ans--;
		}
	}
	cout << ans;
	return 0;
}

bool vis[MAXN];
void dij ()
{
	memset (vis, 0, sizeof (vis));
	dist[1] = 0;
	priority_queue<node>q;
	q.push ({1,0});
	while (!q.empty ())
	{
		node tmp = q.top ();
		q.pop ();
		int i = tmp.i;
		if (vis[i])
			continue;
		else
			vis[i] = 1;
		for (int p = first[i]; p; p = e[p].next)
		{
			int j = e[p].to;
			if (dist[i] + e[p].w < dist[j])
			{
				dist[j] = dist[i] + e[p].w;
				q.push ({j,dist[j]});
				go[j] = p;
			}
			else if (dist[i] + e[p].w == dist[j])
			{
				if (e[p].op == 1)
				{
					continue;
				}
				else
				{
					go[j] = p;
				}
			}
		}
	}
}


#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define int unsigned long long
#define MAXN 800004
using namespace std;
inline int read()
{
int a=0;
bool op = 0;
char c = getchar();
while(c<'0'||c>'9')
{
if (c =='-')
op=1;
c=getchar();
}
while(c>='0'&&c<='9')
{
a = a*10+c-'0';
c=getchar();
}
return op?-a:a;
}
struct edge{
int to,next,w,op;
}e[MAXN<<1];
int ans=0,n,m;
int np = 0,first[MAXN<<1];
void add(int u,int v,int w,int op)
{
e[++np]=(edge){v,first[u],w,op};
first[u]=np;
}
int dist[MAXN<<1];
struct node{
int i,d;
friend bool operator<(node a, node b)
{
return dist[a.i]>dist[b.i];
}
};
void dij();
int go[MAXN<<2];
signed main()
{
n=read(),m=read();
int k=read();
for(int i=1;i<=m;i++)
{
int a=read(),b=read(),c=read();
add(a,b,c,0);
add(b,a,c,0);
}
for(int i=1;i<=n;i++)
dist[i]=INF;
for(int i=1;i<=k;i++)
{
int a=read(),b=read();
add(1,a,b,1);
}
ans = k;
dij();
for(int i=2;i<=n;i++)
{
if(e[go[i]].op==1)
{
ans--;
}
}
cout<<ans;
return 0;
}
bool vis[MAXN];
void dij()
{
memset(vis,0,sizeof(vis));
dist[1]=0;
priority_queue<node>q;
q.push({1,0});
while(!q.empty())
{
node tmp = q.top();
q.pop();
int i=tmp.i;
if(vis[i])
continue;
else
vis[i]=1;
for(int p=first[i];p;p=e[p].next)
{
int j = e[p].to;
if(dist[i]+e[p].w<dist[j])
{
dist[j]=dist[i]+e[p].w;
q.push({j,dist[j]});
go[j]=p;
}
else if(dist[i]+e[p].w == dist[j])
{
if(e[p].op == 1)
{
continue;
}
else
{
go[j]=p;
}
}
}
}
}


#include<cstdio>
#include<iostream>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
#define int unsigned long long
#define MAXN 800004
using namespace std;
inline int read ()
{
	int a = 0;
	bool op = 0;
	char c = getchar ();
	while (c < '0' || c>'9')
	{
		if (c == '-')
			op = 1;
		c = getchar ();
	}
	while (c >= '0' && c <= '9')
	{
		a = a * 10 + c - '0';
		c = getchar ();
	}
	return op ;
}
struct  edge {
	int to, next, w, op;
}e[MAXN << 1];

int ans = 0, n, m;
int np = 0, first[MAXN << 1];
void add (int u, int v, int w, int op)
{
	e[++np] = {v,first[u],w,op};
	first[u] = np;
}

int dist[MAXN << 1];
struct node {
	int i, d;
	friend bool operator<(node a, node b)
	{
		return dist[a.i] > dist[b.i];
	}
};

void dij ();

pair<int, int>wait[MAXN];
int go[MAXN << 2];

signed main ()
{
	n = read (), m = read ();
	int k = read ();
	for (int i = 1; i <= m; i++)
	{
		int a = read (), b = read (), c = read ();
		add (a, b, c, 0);
		add (b, a, c, 0);
	}
	for (int i = 1; i <= n; i++)
		dist[i] = INF;
	for (int i = 1; i <= k; i++)
	{
		int a = read (), b = read ();
		add (1, a, b, 1);
	}
	ans = k;
	dij ();
	for (int i = 2; i <= n; i++)
	{
		if (e[go[i]].op == 1)
		{
			ans--;
		}
	}
	cout << ans;
	return 0;
}

bool vis[MAXN];
void dij ()
{
	memset (vis, 0, sizeof (vis));
	dist[1] = 0;
	priority_queue<node>q;
	q.push ({1,0});
	while (!q.empty ())
	{
		node tmp = q.top ();
		q.pop ();
		int i = tmp.i;
		if (vis[i])
			continue;
		else
			vis[i] = 1;
		for (int p = first[i]; p; p = e[p].next)
		{
			int j = e[p].to;
			if (dist[i] + e[p].w < dist[j])
			{
				dist[j] = dist[i] + e[p].w;
				q.push ({j,dist[j]});
				go[j] = p;
			}
			else if (dist[i] + e[p].w == dist[j])
			{
				if (e[p].op == 1)
				{
					continue;
				}
				else
				{
					go[j] = p;
				}
			}
		}
	}
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[800005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                du[e[i].to]=1;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i]);
        add(b[i],a[i],c[i]);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i]);
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[600005];
int head[100005];
typedef long long lint;
lint d[100005];
ll a[100005],b[100005],c[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i]);
        add(b[i],a[i],c[i]);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        //cout<<d[lo[i]]<<endl;
        if(d[lo[i]]<=trial[i])
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[600005];
int head[100005];
typedef long long lint;
lint d[100005];
ll a[300005],b[300005],c[300005];
map<int,int> length[100005];
vector<int> line[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        if(length[a[i]][b[i]]==0)
        line[a[i]].push_back(b[i]);
        if(length[a[i]][b[i]]==0||length[a[i]][b[i]]>c[i])
        {
            length[a[i]][b[i]]=c[i];
            length[b[i]][a[i]]=c[i];
        }
    }
    for(int i=1;i<=n;++i)
    {
        if(!line[i].empty())
        {
            for(int j=0;j<line[i].size();++j)
            {
                add(i,line[i][j],length[i][line[i][j]]);
                //add(line[i][j],i,length[i][line[i][j]]);
            }
        }
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        //cout<<d[lo[i]]<<endl;
        if(d[lo[i]]<=trial[i])
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[800005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator<(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        if(vis[c.x]==0)
        {
            vis[c.x]=1;
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    ll to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(ll u,ll v,ll w,ll fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    ll x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
void dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 C=ji.top();
        ji.pop();
            for(ll i=head[C.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[C.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[C.x]+e[i].w)
            {
                d[e[i].to]=d[C.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[800005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator<(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        if(vis[c.x]==0)
        {
            vis[c.x]=1;
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    ll to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(ll u,ll v,ll w,ll fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    ll x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 C=ji.top();
        ji.pop();
            for(ll i=head[C.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[C.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[C.x]+e[i].w)
            {
                d[e[i].to]=d[C.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    ll to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(ll u,ll v,ll w,ll fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 C=ji.top();
        ji.pop();
            for(int i=head[C.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[C.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[C.x]+e[i].w)
            {
                d[e[i].to]=d[C.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        if(vis[c.x]==0)
        {
            vis[c.x]=1;
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
using namespace std;
#define inf 1e17
struct s{
   int to;
   long long  val;
   int flag;
   int next;
}edge[1000000];
int head[200010];
int indegree[200010];
int cnt;
void add(int u,int v,long long  w,int flag)
{
    edge[++cnt].to=v;
    edge[cnt].val=w;
    edge[cnt].flag=flag;
    edge[cnt].next=head[u];
    head[u]=cnt;
}
long long dis[200010];
int vis[200010];
int c[100010];
long long  d[100010];
struct s1{
    int x;
    long long  val;
    friend bool operator <(s1 u,s1 v)
    {
        return u.val>v.val;
    }
};
int main()
{
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    memset(indegree,0,sizeof(indegree));
    memset(head,-1,sizeof(head));
    cnt=0;
    memset(edge,0,sizeof(edge));
    for(int i=0;i<m;i++)
    {
        int x,y;
        long long z;
        scanf("%d%d%I64d",&x,&y,&z);
        add(x,y,z,0);
        add(y,x,z,0);
    }
    for(int i=0;i<k;i++)
    {
        scanf("%d%I64d",&c[i],&d[i]);
        add(1,c[i],d[i],1);
        add(c[i],1,d[i],1);
    }
    for(int i=0;i<=n;i++)
    {
        dis[i]=inf;
    }
    dis[1]=0;
    s1 tmp;
    tmp.x=1;
    tmp.val=0;
    priority_queue<s1>q;
    q.push(tmp);
    while(!q.empty())
    {
        s1 temp=q.top();
        q.pop();
        if(vis[temp.x]==0)
        {
            vis[temp.x]=1;
            for(int i=head[temp.x];i!=-1;i=edge[i].next)
            {
                if(dis[edge[i].to]==dis[temp.x]+edge[i].val)
                    indegree[edge[i].to]++;
                if(dis[edge[i].to]>dis[temp.x]+edge[i].val)
                {
                    indegree[edge[i].to]=1;
                    dis[edge[i].to]=dis[temp.x]+edge[i].val;
                    s1 tn;
                    tn.x=edge[i].to;
                    tn.val=dis[edge[i].to];
                    q.push(tn);
                }
            }
        }
    }
    int ans=0;
    for(int i=0;i<k;i++)
    {
        if(dis[c[i]]<d[i])
        {
            ans++;
        }
        else if(dis[c[i]]==d[i])
        {
            if(indegree[c[i]]>1)
            {
                ans++;
                indegree[c[i]]--;
            }
        }
    }
    printf("%d\n",ans);
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[300005];
int head[100005];
typedef long long lint;
lint d[100005];
ll a[100005],b[100005],c[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i]);
        add(b[i],a[i],c[i]);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<=trial[i])
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    ll to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(ll u,ll v,ll w,ll fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    ll x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
void dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 C=ji.top();
        ji.pop();
        if(vis[C.x]==0)
        {
            vis[C.x]=1;
            for(ll i=head[C.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[C.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[C.x]+e[i].w)
            {
                d[e[i].to]=d[C.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        if(vis[c.x]==0)
        {
            vis[c.x]=1;
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 C=ji.top();
        ji.pop();
            for(int i=head[C.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[C.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[C.x]+e[i].w)
            {
                d[e[i].to]=d[C.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                du[lo[i]]--;
                num++;
            }
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[600005];
int head[100005];
typedef long long lint;
lint d[100005];
ll a[300005],b[300005],c[300005];
map<int,int> length[100005];
vector<int> line[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        if(length[a[i]][b[i]]==0)
        line[a[i]].push_back(b[i]);
        if(length[a[i]][b[i]]==0||length[a[i]][b[i]]>c[i])
        {
            length[a[i]][b[i]]=c[i];
            length[b[i]][a[i]]=c[i];
        }
    }
    for(int i=1;i<=n;++i)
    {
        if(!line[i].empty())
        {
            for(int j=0;j<line[i].size();++j)
            {
                add(i,line[i][j],length[i][line[i][j]]);
                add(line[i][j],i,length[i][line[i][j]]);
            }
        }
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        //cout<<d[lo[i]]<<endl;
        if(d[lo[i]]<=trial[i])
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[300005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[100005],b[100005],c[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                du[e[i].to]=1;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i]);
        add(b[i],a[i],c[i]);
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i]);
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next;
    ll w;
}e[600005];
int head[100005];
typedef long long lint;
lint d[100005];
ll a[300005],b[300005],c[300005];
map<int,int> length[100005];
vector<int> line[100005];
int n,m,x,cnt,k;
void add(int u,int v,int w)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    head[u]=cnt++;
}
lint dijkstra()
{
    queue<int> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    if(k==0)
        return 0;
    d[1]=0;
    ji.push(1);
    while(!ji.empty())
    {
        int c=ji.front();
        ji.pop();
        for(int i=head[c];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]>d[c]+e[i].w)
            {
                d[e[i].to]=d[c]+e[i].w;
                    ji.push(e[i].to);
            }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        if(length[a[i]][b[i]]==0)
        line[a[i]].push_back(b[i]);
        if(length[a[i]][b[i]]==0||length[a[i]][b[i]]>c[i])
        {
            length[a[i]][b[i]]=c[i];
            length[b[i]][a[i]]=c[i];
        }
    }
    for(int i=1;i<=n;++i)
    {
        if(!line[i].empty())
        {
            for(int j=0;j<line[i].size();++j)
            {
                add(i,line[i][line[i][j]],length[i][line[i][j]]);
                add(line[i][line[i][j]],i,length[i][line[i][j]]);
            }
        }
    }
    int trial[100005];
    int lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
    }
    dijkstra();
    int num=0;
    for(int i=1;i<=k;++i)
    {
        //cout<<d[lo[i]]<<endl;
        if(d[lo[i]]<=trial[i])
            num++;
    }
    cout<<num<<endl;
}


#include<iostream>
#include<cmath>
#include<cstring>
#include<map>
#include<vector>
#include<queue>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef long double ld;
#define INF 1000000000000000
#define MOD 998244353
struct edge
{
    int to,next,fl;
    ll w;
}e[1000005];
int head[100005];
typedef long long lint;
lint d[100005];
int du[100005];
ll a[300005],b[300005],c[300005];
int n,m,x,cnt,k;
void add(int u,int v,int w,int fl)
{
    e[cnt].to=v;
    e[cnt].w=w;
    e[cnt].next=head[u];
    e[cnt].fl=fl;
    head[u]=cnt++;
}
struct node1
{
    int x;
    ll val;
    friend bool operator <(node1 u, node1 v)
    {
        return u.val>v.val;
    }
};
int vis[100005];
lint dijkstra()
{
    priority_queue<node1> ji;
    for(int i=1;i<=n;++i)
            d[i]=INF;
    d[1]=0;
    node1 be;
    be.x=1;
    be.val=0;
    ji.push(be);
    while(!ji.empty())
    {
        node1 c=ji.top();
        ji.pop();
        if(vis[c.x]==0)
        {
            vis[c.x]=1;
            for(int i=head[c.x];i!=-1;i=e[i].next)
        {
            if(d[e[i].to]==d[c.x]+e[i].w)
                du[e[i].to]++;
            if(d[e[i].to]>d[c.x]+e[i].w)
            {
                d[e[i].to]=d[c.x]+e[i].w;
                du[e[i].to]=1;
                node1 nextl;
                nextl.x=e[i].to;
                nextl.val=d[e[i].to];
                ji.push(nextl);
            }
        }
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<=n;++i)
        head[i]=-1;
    for(int i=1;i<=m;++i)
    {
        cin>>a[i]>>b[i]>>c[i];
        add(a[i],b[i],c[i],0);
        add(b[i],a[i],c[i],0);
    }
    ll trial[100005];
    ll lo[100005];
    for(int i=1;i<=k;++i)
    {
        cin>>lo[i];
        cin>>trial[i];
        add(1,lo[i],trial[i],1);
        add(lo[i],1,trial[i],1);
    }
    dijkstra();
    ll num=0;
    for(int i=1;i<=k;++i)
    {
        if(d[lo[i]]<trial[i])
            num++;
        if(d[lo[i]]==trial[i])
            if(du[lo[i]]>1)
            {
                num++;
                du[lo[i]]--;
            }
    }
    cout<<num<<endl;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <assert.h>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cstdio>
#include <random>
#include <chrono>
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define int long long

using namespace std;

const int INF = 2e15;
const int MOD = 1e9 + 7;

void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	vector<pair<pair<int, int>, int>> edges(m);
	vector<vector<pair<int, int>>> g(n);
	for (int i = 0; i < m; i++) {
		int from, to, w;
		cin >> from >> to >> w;
		from--; to--;
		if (from > to) swap(from, to);
		edges[i] = { {from, to}, w };
	}
	sort(edges.begin(), edges.end());
	for (int i = 0; i < m; i++) {
		if (!i || edges[i].first.first != edges[i - 1].first.first || edges[i].first.second != edges[i - 1].first.second) {
			int from = edges[i].first.first;
			int to = edges[i].first.second;
			int w = edges[i].second;
			g[from].pb({ to, w });
			g[to].pb({ from, w });
		}
	}
	int ans = 0;
	vector<int> roads(n, INF);
	for (int i = 0; i < k; i++) {
		int v, w;
		cin >> v >> w;
		v--;
		if (roads[v] != INF) ans++;
		roads[v] = min(roads[v], w);
	}

	vector<int> d(n, INF);
	d[0] = 0;
	priority_queue<pair<int, int>> q;
	q.push({ 0, 0 });

	while (!q.empty()) {
		auto p = q.top();
		q.pop();
		int w = -p.first;
		int v = p.second;
		if (d[v] < w) continue;

		for (auto & s : g[v]) {
			int u = s.first;
			int w = s.second;
			if (d[u] > w + d[v]) {
				d[u] = w + d[v];
				q.push({ -d[u], u });
			}
		}
	}

	for (int i = 0; i < n; i++) {
		if (roads[i] == INF) continue;
		if (roads[i] >= d[i]) ans++;
	}
	cout << ans;
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cout.precision(12);
	solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <assert.h>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cstdio>
#include <random>
#include <chrono>
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define int long long

using namespace std;

const int INF = 2e15;
const int MOD = 1e9 + 7;

void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	vector<vector<pair<int, int>>> g(n);
	vector<pair<int, pair<int, int>>> edges(m);
	for (int i = 0; i < m; i++) {
		int from, to, w;
		cin >> from >> to >> w;
		from--; to--;
		g[from].eb(to, w);
		g[to].eb(from, w);
		edges[i] = { w, {from, to} };
	}

	vector<pair<int, int>> roads(k);
	for (int i = 0; i < k; i++) {
		int v, w;
		cin >> v >> w;
		v--;
		g[0].eb(v, w);
		g[v].eb(0, w);
		roads[i] = { v, w };
	}

	vector<int> d(n, INF);
	d[0] = 0;
	priority_queue<pair<int, int>> q;
	q.push({0, 0});

	while (!q.empty()) {
		auto & p = q.top();
		q.pop();
		int v = p.second;
		if (d[v] < -p.first) continue;

		for (auto & s : g[v]) {
			int u = s.first;
			int w = s.second;
			if (d[u] > d[v] + w) {
				d[u] = d[v] + w;
				q.push({ -d[u], u });
			}
		}
	}

	vector<int> degrees(n);
	for (int i = 0; i < m; i++) {
		int w = edges[i].first;
		int v = edges[i].second.first;
		int u = edges[i].second.second;
		if (d[v] + w == d[u]) degrees[u]++;
		if (d[u] + w == d[v]) degrees[v]++;
	}

	int ans = 0;
	for (int i = 0; i < k; i++) {
		int v = roads[i].first;
		int w = roads[i].second;
		if (w != d[v] || degrees[v]) ans++;
		else degrees[v]++;
	}

	cout << ans;
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cout.precision(12);
	solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <assert.h>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cstdio>
#include <random>
#include <chrono>
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define int long long

using namespace std;

const int INF = 2e15;
const int MOD = 1e9 + 7;

void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	vector<vector<pair<int, int>>> g(n);
	vector<pair<int, pair<int, int>>> edges(m);
	for (int i = 0; i < m; i++) {
		int from, to, w;
		cin >> from >> to >> w;
		from--; to--;
		g[from].eb(to, w);
		g[to].eb(from, w);
		edges[i] = { w, {from, to} };
	}

	vector<pair<int, int>> roads(k);
	for (int i = 0; i < k; i++) {
		int v, w;
		cin >> v >> w;
		v--;
		g[0].eb(v, w);
		g[v].eb(0, w);
		roads[i] = { v, w };
	}

	vector<int> d(n, INF);
	d[0] = 0;
	priority_queue<pair<int, int>> q;
	q.push({0, 0});

	while (!q.empty()) {
		auto & p = q.top();
		q.pop();
		int v = p.second;
		if (d[v] < -p.first) continue;

		for (auto & s : g[v]) {
			int u = s.first;
			int w = s.second;
			if (d[u] > d[v] + w) {
				d[u] = d[v] + w;
				q.push({ -d[u], u });
			}
		}
	}

	vector<int> degrees(n);
	for (int i = 0; i < m; i++) {
		int w = edges[i].first;
		int v = edges[i].second.first;
		int u = edges[i].second.second;
		if (d[v] + w == d[u]) degrees[u]++;
		if (d[u] + w == d[v]) degrees[v]++;
	}

	int ans = 0;
	for (int i = 0; i < k; i++) {
		int v = roads[i].first;
		int w = roads[i].second;
		if (w > d[v] || degrees[v]) ans++;
		else degrees[v]++;
	}

	cout << ans;
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cout.precision(12);
	solve();
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <algorithm>
#include <stack>
#include <string>
#include <assert.h>
#include <queue>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cstdio>
#include <random>
#include <chrono>
#define ll long long
#define ld long double
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define int long long

using namespace std;

const int INF = 2e15;
const int MOD = 1e9 + 7;

void solve() {
	int n, m, k;
	cin >> n >> m >> k;
	vector<vector<pair<int, int>>> g(n);
	vector<pair<int, pair<int, int>>> edges(m);
	for (int i = 0; i < m; i++) {
		int from, to, w;
		cin >> from >> to >> w;
		from--; to--;
		g[from].eb(to, w);
		g[to].eb(from, w);
		edges[i] = { w, {from, to} };
	}

	vector<pair<int, int>> roads(k);
	for (int i = 0; i < k; i++) {
		int v, w;
		cin >> v >> w;
		v--;
		g[0].eb(v, w);
		g[v].eb(0, w);
		roads[i] = { v, w };
	}

	vector<int> d(n, INF);
	d[0] = 0;
	set<pair<int, int>> q;
	q.insert({0, 0});

	while (!q.empty()) {
		auto p = *q.begin();
		q.erase(q.begin());
		int v = p.second;

		for (auto & s : g[v]) {
			int u = s.first;
			int w = s.second;
			if (d[u] > d[v] + w) {
				q.erase({d[u], u});
				d[u] = d[v] + w;
				q.insert({ d[u], u });
			}
		}
	}

	vector<int> degrees(n);
	for (int i = 0; i < m; i++) {
		int w = edges[i].first;
		int v = edges[i].second.first;
		int u = edges[i].second.second;
		if (d[v] + w == d[u]) degrees[u]++;
		if (d[u] + w == d[v]) degrees[v]++;
	}

	int ans = 0;
	for (int i = 0; i < k; i++) {
		int v = roads[i].first;
		int w = roads[i].second;
		if (w > d[v] || degrees[v]) ans++;
		else degrees[v]++;
	}

	cout << ans;
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	cout.precision(12);
	solve();
}


#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <cstdlib>
#include <queue>
#include <set>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <bitset>
#include <sstream>
#include <cassert>

using namespace std;

int main(){
	//freopen("input.txt","r",stdin);
	//freopen("output.txt","w",stdout);
	ios_base::sync_with_stdio(false);
	int n, m, k;
	cin >> n >> m >> k;
	vector<vector<pair<int, int> > > g(n);
	for (int i = 0; i < m; ++i) {
		int x, y, z;
		cin >> x >> y >> z;
		--x, --y;
		g[x].push_back(make_pair(y, z));
		g[y].push_back(make_pair(x, z));
	}
	int ans = 0;
	vector<int> e(n, -1);
	for (int i = 0; i < k; ++i) {
		int y, z;
		cin >> y >> z;
		--y;
		if (e[y] != -1) {
			++ans;
			e[y] = min(e[y], z);
		}
		else
			e[y] = z;
	}
	const long long INF = 1e18;
	vector<long long> d(n, INF);
	vector<bool> p(n);
	set<pair<long long, int> > s;
	for (int i = 1; i < n; ++i)
		s.insert(make_pair(INF, i));
	s.insert(make_pair(0, 0));
	while (!s.empty()) {
		pair<long long, int> fr = *s.begin();
		s.erase(s.begin());
		int v = fr.second;
		long long dist = fr.first;
		d[v] = dist;
		for (int i = 0; i < g[v].size(); ++i) {
			int to = g[v][i].first, c = g[v][i].second;
			if (d[v] + c <= d[to]) {
				s.erase(s.find(make_pair(d[to], to)));
				d[to] = d[v] + c;
				p[to] = false;
				s.insert(make_pair(d[to], to));
			}
		}
		if (v == 0) {
			for (int i = 1; i < n; ++i)
				if (e[i] != -1) {
					int c = e[i];
					if (d[v] + c < d[i]) {
						s.erase(s.find(make_pair(d[i], i)));
						d[i] = d[v] + c;
						p[i] = true;
						s.insert(make_pair(d[i], i));
					}
				}
		}
	}
	for (int i = 1; i < n; ++i)
		if (e[i] != -1 && !p[i])
			++ans;
	cout << ans;
	return 0;
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 10000000000000
#define INF2 1000000007
using namespace std;
int n, v;
bool vis[2001];
vector <vector <pair<int, int> > > adjlist;
long long int matrix[2001][2001];
int orgmat[2001][2001];
long long int mindist[2001];
int workingindex1[2001];
int workingindex2[2001];
long long int minim(long long int a, long long int b) {
	return (a > b ? b : a);
}
void dfs(int loc, long long int dist, int basis) {
	if (!vis[loc]) {
		vis[loc] = true;
		for (int i = 0; i < adjlist[loc].size(); i++) {
			dfs(adjlist[loc][i].first, dist + adjlist[loc][i].second, basis);
		}
		matrix[basis][loc] = dist;
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n;
	adjlist.resize(n + 1);
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			matrix[i][j] = INF;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> v;
			orgmat[i][j] = v;
		}
	}
	for (int i = 0; i < n; i++)
		mindist[i] = INF;
	int curnode = 0;
	int cnter = 0;
	while (true) {
		int minval = INF2;
		int minnode = -1;
		for (int j = 0; j < n; j++) {
			if (curnode == j)
				continue;
			if (mindist[j] > orgmat[curnode][j] && orgmat[curnode][j] != 0) {
				workingindex1[j] = curnode;
				workingindex2[j] = j;
			}
			mindist[j] = minim(mindist[j], orgmat[curnode][j]);
			if (mindist[j] != 0 && mindist[j] < minval) {
				minval = mindist[j];
				minnode = j;
			}
			cnter++;
			//cout << mindist[j] << ' ';
		}
		//cout << '\n';
		if (minval != INF2)
			mindist[minnode] = 0;
		if (minval != INF2) {
			adjlist[workingindex1[minnode]].push_back(make_pair(workingindex2[minnode], minval));
			adjlist[workingindex2[minnode]].push_back(make_pair(workingindex1[minnode], minval));
		}
		//cout << curnode << ' ' << minnode << ' ' << minval << '\n';
		if (minval != INF2)
			curnode = minnode;
		else break;
		if (cnter >= 10000000)
			cout << "GG\n";
	}

	/*for (int i = 0; i < adjlist.size(); i++) {
		cout << i << " | ";
		for (int j = 0; j < adjlist[i].size(); j++) {
			cout << adjlist[i][j].first << " AND " << adjlist[i][j].second << ' ';
		}
		cout << '\n';
	}*/

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++)
			vis[j] = false;
		dfs(i, 0, i);
	}
	bool same = true;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			//cout << matrix[i][j] << ' ';
			if (orgmat[i][j] != matrix[i][j])
				same = false;
		}
		//cout << '\n';
	}
	for (int i = 0; i < n; i++)
		if (orgmat[i][i] != 0)
			same = false;
	if (same)
		cout << "YES\n";
	else
		cout << "NO\n";
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
bool counted[100001];
long long int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<long long int, pair<long long int, long long int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		adjlist[loc].push_back(make_pair(1, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << sdist[i] << ' ';
	//cout << '\n';
	for (int i = 0; i < edgelist.size(); i++) {
		if (sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first) {
			inadj[edgelist[i].second.first]++;
			//cout << "TAKEN\n";
		}
		else if (sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) {
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k) {
			//cout << i << "HI\n";
			counted[i] = true;
			//cout << "NOT TAKEN\n";
		}
		//else cout << "NOT TAKEN and NOT TRAIN\n";
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << inadj[i] << ' ';
	//cout << '\n';
	//cout << "CURANS:" << ans << '\n';
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		if (inadj[edgelist[i].second.second] > 1 && !counted[i]) {
			inadj[edgelist[i].second.second]--;
			counted[i] = true;
		}
	}
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		ans += counted[i];
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<int, pair<int, int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		adjlist[loc].push_back(make_pair(1, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	for (int i = 0; i < edgelist.size(); i++) {
		if (sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first) {
			inadj[edgelist[i].second.first]++;
			//cout << "TAKEN\n";
		}
		else if (sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) {
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k) {
			ans++;
			inadj[edgelist[i].second.second] = -1000000000;
			//cout << "NOT TAKEN\n";
		}
		//else cout << "NOT TAKEN and NOT TRAIN\n";
	}
	//cout << "CURANS:" << ans << '\n';
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		if (inadj[edgelist[i].second.second] > 1) {
			inadj[edgelist[i].second.second]--;
			ans++;
		}
	}

	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
bool counted[100001];
int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<int, pair<int, int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		adjlist[loc].push_back(make_pair(1, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << sdist[i] << ' ';
	//cout << '\n';
	for (int i = 0; i < edgelist.size(); i++) {
		if (sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first) {
			inadj[edgelist[i].second.first]++;
			//cout << "TAKEN\n";
		}
		else if (sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) {
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k) {
			//cout << i << "HI\n";
			counted[i] = true;
			//cout << "NOT TAKEN\n";
		}
		//else cout << "NOT TAKEN and NOT TRAIN\n";
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << inadj[i] << ' ';
	//cout << '\n';
	//cout << "CURANS:" << ans << '\n';
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		if (inadj[edgelist[i].second.second] > 1 && !counted[i]) {
			inadj[edgelist[i].second.second]--;
			counted[i] = true;
		}
	}
	for (int i = 0; i < edgelist.size(); i++) {
		ans += counted[i];
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int setdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
		setdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		if (setdist[loc] != INF) {
			ans++;
		}
		setdist[loc] = minim(setdist[loc], dist);
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}

	for (int i = 1; i <= n; i++) {
		if (setdist[i] == INF)
			setdist[i] = -1;
	}
	for (int i = 2; i <= n; i++) {
		if (sdist[i] <= setdist[i]) {
			//cout << sdist[i] << ' ' << setdist[i] << '\n';
			ans++;
		}
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 1000000007
using namespace std;
int sdist[100001];
int setdist[100001];
int a, b, w;
int n, m, k;
int loc, dist;
int ans = 0;
vector <vector <pair<int, int> > > adjlist;
priority_queue<pair<int, int>, vector <pair<int, int> >, greater<pair<int, int> > > pq;
int main() {
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
		setdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		if (setdist[loc] != INF) {
			ans++;
		}
		setdist[loc] = min(setdist[loc], dist);
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		int curloc = pq.top().second;
		int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}

	for (int i = 1; i <= n; i++) {
		if (setdist[loc] == INF)
			setdist[loc] = -1;
	}
	for (int i = 2; i <= n; i++) {
		if (sdist[i] <= setdist[i])
			ans++;
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
bool counted[100001];
int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<int, pair<int, int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		adjlist[loc].push_back(make_pair(1, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	for (int i = 0; i < edgelist.size(); i++) {
		if (sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first) {
			inadj[edgelist[i].second.first]++;
			//cout << "TAKEN\n";
		}
		else if (sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) {
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k) {
			ans++;
			counted[i] = true;
			//cout << "NOT TAKEN\n";
		}
		//else cout << "NOT TAKEN and NOT TRAIN\n";
	}
	//cout << "CURANS:" << ans << '\n';
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		if (inadj[edgelist[i].second.second] > 1 && !counted[i]) {
			inadj[edgelist[i].second.second]--;
			counted[i] = true;
		}
	}
	for (int i = 1; i <= n; i++) {
		ans += counted[i];
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 1000000007
using namespace std;
int sdist[100001];
int setdist[100001];
int a, b, w;
int n, m, k;
int loc, dist;
int ans = 0;
vector <vector <pair<int, int> > > adjlist;
priority_queue<pair<int, int>, vector <pair<int, int> >, greater<pair<int, int> > > pq;
int main() {
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
		setdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		if (setdist[loc] != INF) {
			ans++;
		}
		setdist[loc] = min(setdist[loc], dist);
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		int curloc = pq.top().second;
		int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}

	for (int i = 1; i <= n; i++) {
		if (setdist[i] == INF)
			setdist[i] = -1;
	}
	for (int i = 2; i <= n; i++) {
		if (sdist[i] <= setdist[i]) {
			//cout << sdist[i] << ' ' << setdist[i] << '\n';
			ans++;
		}
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int setdist[100001];
int a, b, w;
int n, m, k;
int loc, dist;
int ans = 0;
vector <vector <pair<int, int> > > adjlist;
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
		setdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		if (setdist[loc] != INF) {
			ans++;
		}
		setdist[loc] = minim(setdist[loc], dist);
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}

	for (int i = 1; i <= n; i++) {
		if (setdist[i] == INF)
			setdist[i] = -1;
	}
	for (int i = 2; i <= n; i++) {
		if (sdist[i] <= setdist[i]) {
			//cout << sdist[i] << ' ' << setdist[i] << '\n';
			ans++;
		}
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<int, pair<int, int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	for (int i = 0; i < edgelist.size(); i++) {
		if ((sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first || sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) && i < edgelist.size() - k) {
			inadj[edgelist[i].second.first]++;
			inadj[edgelist[i].second.second]++;
		}
		else if ((sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first || sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) && (!inadj[edgelist[i].second.second] || !inadj[edgelist[i].second.first])) {
			inadj[edgelist[i].second.first]++;
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k)
			ans++;

	}

	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
bool counted[400001];
long long int inadj[100001];
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
vector <pair<long long int, pair<long long int, long long int> > > edgelist;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	//incorrect program
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
		edgelist.push_back(make_pair(w, make_pair(a, b)));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		adjlist[1].push_back(make_pair(loc, dist));
		adjlist[loc].push_back(make_pair(1, dist));
		edgelist.push_back(make_pair(dist, make_pair(1, loc)));
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		long long int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << sdist[i] << ' ';
	//cout << '\n';
	for (int i = 0; i < edgelist.size(); i++) {
		if (sdist[edgelist[i].second.first] == sdist[edgelist[i].second.second] + edgelist[i].first) {
			inadj[edgelist[i].second.first]++;
			//cout << "TAKEN\n";
		}
		else if (sdist[edgelist[i].second.second] == sdist[edgelist[i].second.first] + edgelist[i].first) {
			inadj[edgelist[i].second.second]++;
		}
		else if (i >= edgelist.size() - k) {
			//cout << i << "HI\n";
			counted[i] = true;
			//cout << "NOT TAKEN\n";
		}
		//else cout << "NOT TAKEN and NOT TRAIN\n";
	}
	//for (int i = 0; i <= 5; i++)
	//	cout << inadj[i] << ' ';
	//cout << '\n';
	//cout << "CURANS:" << ans << '\n';
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		if (inadj[edgelist[i].second.second] > 1 && !counted[i]) {
			inadj[edgelist[i].second.second]--;
			counted[i] = true;
		}
	}
	for (int i = edgelist.size() - 1; i >= edgelist.size() - k; i--) {
		ans += counted[i];
	}
	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <queue>
#define INF 10000000000000000LL
using namespace std;
long long int sdist[100001];
long long int setdist[100001];
long long int a, b, w;
long long int n, m, k;
long long int loc, dist;
long long int ans = 0;
vector <vector <pair<int, long long int> > > adjlist;
priority_queue<pair<long long int, int>, vector <pair<long long int, int> >, greater<pair<long long int, int> > > pq;
long long int minim(long long int a, long long int b) {
	return (a > b) ? b : a;
}
int main() {
	cin >> n >> m >> k;
	adjlist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		sdist[i] = INF;
		setdist[i] = INF;
	}
	for (int i = 0; i < m; i++) {
		cin >> a >> b >> w;
		adjlist[a].push_back(make_pair(b, w));
		adjlist[b].push_back(make_pair(a, w));
	}
	for (int j = 0; j < k; j++) {
		cin >> loc >> dist;
		if (setdist[loc] != INF) {
			ans++;
		}
		setdist[loc] = minim(setdist[loc], dist);
	}
	pq.push(make_pair(0, 1));
	while (!pq.empty()) {
		int curloc = pq.top().second;
		long long int curdist = pq.top().first;
		pq.pop();
		if (sdist[curloc] > curdist) {
			sdist[curloc] = curdist;
			for (int i = 0; i < adjlist[curloc].size(); i++)
				pq.push(make_pair(curdist + adjlist[curloc][i].second, adjlist[curloc][i].first));
		}
	}

	for (int i = 1; i <= n; i++) {
		if (setdist[i] == INF)
			setdist[i] = -1;
	}
	for (int i = 2; i <= n; i++) {
		if (sdist[i] <= setdist[i] && !(sdist[i] == INF && setdist[i] == INF)) {
			//cout << sdist[i] << ' ' << setdist[i] << '\n';
			ans++;
		}
	}
	cout << ans << '\n';
}


#if 1
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <list>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> pii;

const LD eps = 1e-9;
const LD pi = acos(-1.0);
const LL inf = 1e+9;

#define mp make_pair
#define pb push_back
#define X first
#define Y second

#define dbg(x) { cerr << #x << " = " << x << endl; }

// extended template
#pragma comment(linker, "/STACK:36777216")
typedef vector<int> vi;
typedef vector<vi> vvi;

#define forn(i, n) for (int i = 0; i < n; ++i)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()

template<typename T> istream & operator >> (istream &, vector<T> &);
template<typename T> ostream & operator << (ostream &, const vector<T> &);

#define START clock_t _clock = clock();
#define END cerr << endl << "time: " << (clock() - _clock) / LD(CLOCKS_PER_SEC) << endl;

#define NAME "problem"

vector <vector <pii> > g, g2;
vector <int> used;
vector <LL> d2;

void dfs(int v)
{
	used[v] = 1;
	for (int i = 0; i < g2[v].size(); i++)
	{
		int to = g2[v][i].X;
		int c = g2[v][i].Y;
		if (d2[to] == d2[v] + c && !used[to])
		{
			 dfs(to);
		}
	}
}
int main()
{
    START
    // freopen(NAME ".in", "r", stdin); freopen(NAME ".out", "w", stdout);
    //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout);

	int n, m, k;
	scanf("%d %d %d",&n, &m, &k);
	g.resize(n);
	g2.resize(n);
	for (int i = 0; i < m; i++)
	{
		int x, y, c;
		scanf("%d %d %d", &x, &y, &c);
		x--;y--;
		g[x].pb(mp(y, c));
		g[y].pb(mp(x, c));
	}
	vector <LL> d(n, LL(inf) * inf);
	d[0] = 0;
	set<pair<LL, int> > q;
	q.insert(mp(d[0], 0));
	while (!q.empty())
	{
		int v = q.begin()->Y;
		q.erase(q.begin());

		for (int i = 0; i < g[v].size(); i++)
		{
			int to = g[v][i].X;
			int cost = g[v][i].Y;
			if (d[to] > d[v] + cost)
			{
				q.erase(mp(d[to],to));
				d[to] = d[v] + cost;
				q.insert(mp(d[to], to));
			}
		}
	}

	g2 = g;
	d2 = d;
	vector <pii> ed;
	for (int i = 0; i < k; i++)
	{
		int x, c;
		scanf("%d %d", &x, &c);
		x--;
		g2[0].pb(mp(x, c));
		g2[x].pb(mp(0, c));
		ed.pb(mp(x, c));
	}

	q.insert(mp(d2[0], 0));
	while (!q.empty())
	{
		int v = q.begin()->Y;
		q.erase(q.begin());

		for (int i = 0; i < g2[v].size(); i++)
		{
			int to = g2[v][i].X;
			int cost = g2[v][i].Y;
			if (d2[to] > d2[v] + cost)
			{
				q.erase(mp(d2[to],to));
				d2[to] = d2[v] + cost;
				q.insert(mp(d2[to], to));
			}
		}
	}

	LL cnt = 0;
	used.assign(n, 0);
	for (int i = 0; i < k; i++)
	{
		int to = ed[i].X;
		int cost = ed[i].Y;
		bool fl = true;
		if (cost == d2[to] && cost < d[to] && !used[to])
		{
			for (int j = 0; j < g[to].size(); j++)
			{
				int v = g[to][i].X;
				int c = g[to][i].Y;
				if (d2[v] + c == d2[to])
					fl = false;

			}
		}
		if(fl)
		{
			dfs(to);
				cnt++;
		}
	}

	cout << k - cnt << endl;
    END
    return 0;
}
/*******************************************
*******************************************/

template<typename T> istream & operator >> (istream &is, vector<T> &v)
{
    forn(i, v.size())
        is >> v[i];
    return is;
}
template<typename T> ostream & operator << (ostream &os, const vector<T> &v)
{
    forn(i, v.size())
        os << v[i] << " ";
    return os;
}
#endif


#if 1
#include <functional>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <iomanip>
#include <sstream>
#include <numeric>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <list>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> pii;

const LD eps = 1e-9;
const LD pi = acos(-1.0);
const LL inf = 1e+9;

#define mp make_pair
#define pb push_back
#define X first
#define Y second

#define dbg(x) { cerr << #x << " = " << x << endl; }

// extended template
#pragma comment(linker, "/STACK:36777216")
typedef vector<int> vi;
typedef vector<vi> vvi;

#define forn(i, n) for (int i = 0; i < n; ++i)
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()

template<typename T> istream & operator >> (istream &, vector<T> &);
template<typename T> ostream & operator << (ostream &, const vector<T> &);

#define START clock_t _clock = clock();
#define END cerr << endl << "time: " << (clock() - _clock) / LD(CLOCKS_PER_SEC) << endl;

#define NAME "problem"

vector <vector <pii> > g, g2;
vector <int> used;
vector <LL> d2;

void dfs(int v)
{
	used[v] = 1;
	for (int i = 0; i < g2[v].size(); i++)
	{
		int to = g2[v][i].X;
		int c = g2[v][i].Y;
		if ((d2[to] == d2[v] + c) && !used[to])
		{
			 dfs(to);
		}
	}
}
int main()
{
    START
    // freopen(NAME ".in", "r", stdin); freopen(NAME ".out", "w", stdout);
    //freopen("input.txt", "r", stdin); //freopen("output.txt", "w", stdout);

	int n, m, k;
	scanf("%d %d %d",&n, &m, &k);
	g.resize(n);
	g2.resize(n);
	for (int i = 0; i < m; i++)
	{
		int x, y, c;
		scanf("%d %d %d", &x, &y, &c);
		x--;y--;
		g[x].pb(mp(y, c));
		g[y].pb(mp(x, c));
	}
	vector <LL> d(n, LL(inf) * inf);
	d[0] = 0;
	set<pair<LL, int> > q;
	q.insert(mp(d[0], 0));
	while (!q.empty())
	{
		int v = q.begin()->Y;
		q.erase(q.begin());

		for (int i = 0; i < g[v].size(); i++)
		{
			int to = g[v][i].X;
			int cost = g[v][i].Y;
			if (d[to] > d[v] + cost)
			{
				q.erase(mp(d[to],to));
				d[to] = d[v] + cost;
				q.insert(mp(d[to], to));
			}
		}
	}

	g2 = g;
	d2 = d;
	vector <pii> ed;
	for (int i = 0; i < k; i++)
	{
		int x, c;
		scanf("%d %d", &x, &c);
		x--;
		g2[0].pb(mp(x, c));
		g2[x].pb(mp(0, c));
		ed.pb(mp(x, c));
	}

	q.insert(mp(d2[0], 0));
	while (!q.empty())
	{
		int v = q.begin()->Y;
		q.erase(q.begin());

		for (int i = 0; i < g2[v].size(); i++)
		{
			int to = g2[v][i].X;
			int cost = g2[v][i].Y;
			if (d2[to] > d2[v] + cost)
			{
				q.erase(mp(d2[to],to));
				d2[to] = d2[v] + cost;
				q.insert(mp(d2[to], to));
			}
		}
	}

	LL cnt = 0;
	used.assign(n, 0);
	for (int i = 0; i < k; i++)
	{
		int to = ed[i].X;
		int cost = ed[i].Y;
		if (cost == d2[to] && cost < d[to] && !used[to])
		{
			dfs(to);
			cnt++;
		}
	}

	cout << k - cnt << endl;
    END
    return 0;
}
/*******************************************
*******************************************/

template<typename T> istream & operator >> (istream &is, vector<T> &v)
{
    forn(i, v.size())
        is >> v[i];
    return is;
}
template<typename T> ostream & operator << (ostream &os, const vector<T> &v)
{
    forn(i, v.size())
        os << v[i] << " ";
    return os;
}
#endif