#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<cstring>
#include<algorithm>
#include <climits>
#include <cmath>
#include<cstdlib>
#include<cstdio>
#include <cctype>
#include<iostream>
#include<sstream>
#include<ctime>
using namespace std;

#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define DEBUG if(0)
#define SZ(c) c.size()
#define ALL(x) x.begin(),x.end()
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define PII pair<int, int>
#define PSI pair<string, int>
#define VI vector<int>
#define VS vector<string>
#define VVI vector< VI >
#define VPI vector< PII >
#define LL long long
#define ULL unsigned long long
#define SET(p) memset(p, -1, sizeof(p))
#define CLR(p) memset(p, 0, sizeof(p))
#define MEM(p, v) memset(p, v, sizeof(p))
#define CPY(d, s) memcpy(d, s, sizeof(s))
#define FOR(i,a,b) for(int i=(int)(a);i<=(int)(b);++i)
#define FORD(i,a,b) for(int i=(int)(a);i>=(int)(b);--i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define REPR(i,n) for(int i=(int)n-1; i>=0; --i)
#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)

template< class T > T _abs(T n) { return (n < 0 ? -n : n); }
template< class T > T _max(T a, T b) { return (!(a < b) ? a : b); }
template< class T > T _min(T a, T b) { return (a < b ? a : b); }
template< class T > T sq(T x) { return x * x; }
template< class T > void setmax(T &a, T b) { if(a < b) a = b; }
template< class T > void setmin(T &a, T b) { if(b < a) a = b; }
template< class T > T GCD(const T a, const T b) { return (b ? GCD<T>(b, a%b) : a); }
template< class T > T LCM(const T a, const T b) { return (a / GCD<T>(a, b) * b); }
template< class T > T mod(const T &a, const T &b) { return (a < b ? a : a % b); }
template< class T > bool inrange(const T &a, const T &b, const T &c) { return a<=b && b<=c; }

const int INF=1000000007;
const int MOD=1000000007;
const LL LINF = 1ll << 60;

int dy8[] = {-1,  -1,  -1,  0,  0,  0,  1,  1};
int dx8[] = {-1,  0,  1,  -1,  0,  1,  -1,  0};

int dx4[]={1,-1,0,0};
int dy4[]={0,0,1,-1};

VS parse(string s, string c)
{
  int len = c.length(), p = -len, np;
  VS ans;

  do
    {
      np = s.find(c, p+len);
      ans.push_back(s.substr(p+len, np - p - len));
      p = np;
    }
  while (p != string::npos);

  return ans;
}

// calculates n raised to kth power modulo MOD
long modPow(long n, long k)
{
    long r = 1;
    while (k)
    {
        if (k&1)
        {
            r = (r*n) % MOD;
        }
        n = (n*n) % MOD;
        k >>= 1;
    }
    return r % MOD;
}

int mul(int a, int b)
{
    return ((LL)a*b)%MOD;
}

int pw(int base, int expo)
{
    if(expo==0) return 1;
    if(expo&1) return mul(base, pw(base, expo-1));
    int root=pw(base, expo/2);
    return mul(root, root);
}

int mod_inv(int K)
{
    return pw(K, MOD-2);
}

const int MAX=100002;

int n, m, k;
VPI graph[MAX];
LL dist[MAX];
bool trains[MAX];
int dtrains[MAX];
int nspath[MAX];

int main()
{
    //READ("in.txt");
    //WRITE("out.txt");

    int u, v, w;
    cin>>n>>m>>k;
    int res=0;
    REP(i, m)
    {
        cin>>u>>v>>w;
        graph[u].PB(MP(w, v));
        graph[v].PB(MP(w, u));
    }

    REP(i, k)
    {
        cin>>v>>w;
        if(!trains[v])
        {
          trains[v]=true;
          dtrains[v]=w;
        }
        else
        {
            dtrains[v]=min(dtrains[v], w);
            res++;
        }

    }

    FOR(i, 1, n) if(trains[i])
    {
        graph[1].PB(MP(dtrains[i], i));
        graph[i].PB(MP(dtrains[i], 1));
    }

    REP(i, MAX) dist[i]=LINF;

    priority_queue<PII, VPI, greater<PII> > pq;
    pq.push(MP(0, 1));
    dist[1]=0; nspath[1]=1;
    while(!pq.empty())
    {
        u=pq.top().second;
        pq.pop();
        REP(i, SZ(graph[u]))
        {
            v=graph[u][i].second;
            w=graph[u][i].first;
            if(dist[v]>dist[u]+w)
            {
                dist[v]=dist[u]+w;
                pq.push(MP(dist[v], v));
                nspath[v]=1;
            }
            else if(dist[v]==dist[u]+w)
            {
                nspath[v]++;
            }
        }
    }

    REP(i, n+1) if(trains[i])
    {
        if(dist[i]<dtrains[i] || (dist[i]==dtrains[i] && nspath[i]>1))
        {
            res++;
            nspath[i]--;
        }
    }
    cout<<res;
    return 0;
}


#include<vector>
#include<stack>
#include<set>
#include<map>
#include<queue>
#include<deque>
#include<cstring>
#include<algorithm>
#include <climits>
#include <cmath>
#include<cstdlib>
#include<cstdio>
#include <cctype>
#include<iostream>
#include<sstream>
#include<ctime>
using namespace std;

#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define DEBUG if(0)
#define SZ(c) c.size()
#define ALL(x) x.begin(),x.end()
#define ff first
#define ss second
#define MP make_pair
#define PB push_back
#define PII pair<int, int>
#define PSI pair<string, int>
#define VI vector<int>
#define VS vector<string>
#define VVI vector< VI >
#define VPI vector< PII >
#define LL long long
#define ULL unsigned long long
#define SET(p) memset(p, -1, sizeof(p))
#define CLR(p) memset(p, 0, sizeof(p))
#define MEM(p, v) memset(p, v, sizeof(p))
#define CPY(d, s) memcpy(d, s, sizeof(s))
#define FOR(i,a,b) for(int i=(int)(a);i<=(int)(b);++i)
#define FORD(i,a,b) for(int i=(int)(a);i>=(int)(b);--i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define REPR(i,n) for(int i=(int)n-1; i>=0; --i)
#define FOREACH(it,c) for(typeof((c).begin()) it=(c).begin();it!=(c).end();++it)

template< class T > T _abs(T n) { return (n < 0 ? -n : n); }
template< class T > T _max(T a, T b) { return (!(a < b) ? a : b); }
template< class T > T _min(T a, T b) { return (a < b ? a : b); }
template< class T > T sq(T x) { return x * x; }
template< class T > void setmax(T &a, T b) { if(a < b) a = b; }
template< class T > void setmin(T &a, T b) { if(b < a) a = b; }
template< class T > T GCD(const T a, const T b) { return (b ? GCD<T>(b, a%b) : a); }
template< class T > T LCM(const T a, const T b) { return (a / GCD<T>(a, b) * b); }
template< class T > T mod(const T &a, const T &b) { return (a < b ? a : a % b); }
template< class T > bool inrange(const T &a, const T &b, const T &c) { return a<=b && b<=c; }

const int INF=1000000007;
const int MOD=1000000007;

int dy8[] = {-1,  -1,  -1,  0,  0,  0,  1,  1};
int dx8[] = {-1,  0,  1,  -1,  0,  1,  -1,  0};

int dx4[]={1,-1,0,0};
int dy4[]={0,0,1,-1};

VS parse(string s, string c)
{
  int len = c.length(), p = -len, np;
  VS ans;

  do
    {
      np = s.find(c, p+len);
      ans.push_back(s.substr(p+len, np - p - len));
      p = np;
    }
  while (p != string::npos);

  return ans;
}

// calculates n raised to kth power modulo MOD
long modPow(long n, long k)
{
    long r = 1;
    while (k)
    {
        if (k&1)
        {
            r = (r*n) % MOD;
        }
        n = (n*n) % MOD;
        k >>= 1;
    }
    return r % MOD;
}

int mul(int a, int b)
{
    return ((LL)a*b)%MOD;
}

int pw(int base, int expo)
{
    if(expo==0) return 1;
    if(expo&1) return mul(base, pw(base, expo-1));
    int root=pw(base, expo/2);
    return mul(root, root);
}

int mod_inv(int K)
{
    return pw(K, MOD-2);
}

const int MAX=100002;

int n, m, k;
VPI graph[MAX];
int dist[MAX];

int main()
{
    //READ("in.txt");
    //WRITE("out.txt");

    int u, v, w;
    cin>>n>>m>>k;
    int res=0;
    REP(i, m)
    {
        cin>>u>>v>>w;
        graph[u].PB(MP(w, v));
        graph[v].PB(MP(w, u));
    }
    priority_queue<PII, VPI, greater<PII> > pq;
    pq.push(MP(0, 1));
    dist[1]=0;
    while(!pq.empty())
    {
        u=pq.top().second;
        pq.pop();
        REP(i, SZ(graph[u]))
        {
            v=graph[u][i].second;
            w=graph[u][i].first;
            if(dist[v]==0 || dist[v]>dist[u]+w)
            {
                dist[v]=dist[u]+w;
                pq.push(MP(dist[v], v));
            }
        }
    }

    REP(i,k)
    {
        cin>>v>>w;
        if(w>=dist[v]) res++;
    }
    cout<<res;
    return 0;
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,ans,l,r,pt;
bool vis[1000010];
LL q[10000010];
LL dist[1000010];
LL st[600010],ne[600010],go[600010],w[600010];
void Add(LL x,LL y,LL k){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k),Add(y,x,k);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	if (r>10000010)printf("- -");
	for (LL i=1;i<=K;i++){
		scanf("%I64d%I64d",&y,&k);
		if (dist[y]<=k)ans++;
	}
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,ans,l,r,pt;
bool vis[100010];
LL q[10000010];
LL dist[100010];
LL st[600010],ne[600010],go[600010],w[600010];
void Add(LL x,LL y,LL k){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k),Add(y,x,k);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	if (r>10000010)printf("- -");
	for (LL i=1;i<=K;i++){
		scanf("%I64d%I64d",&y,&k);
		if (dist[y]<=k)ans++;
	}
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
int N,M,K,x,y,k,pt,l,r,ans;
int q[200010],vis[200010];
LL dist[200010];
int in[200010];
int st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(int x,int y,int k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%d%d%d",&N,&M,&K);
	for (int i=1;i<=M;i++)scanf("%d%d%d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (int i=1;i<=K;i++)scanf("%d%d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;q[0]=1;vis[1]=true;
	for (l=0,r=1;l!=r;){
		int x=q[l];
		l++;if (l>=N)l-=N;
		vis[x]=false;
		for (int i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[r]=go[i];
				++r;
				if (r>=N)r-=N;
				vis[go[i]]=true;
			}
		}
	}
	for (int i=1;i<=N;i++)
	for (int j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (int j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (int j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
int N,M,K,x,y,k,pt,l,r,ans,last;
int q[200010],vis[200010];
LL dist[200010];
int in[200010];
int st[200010],ne[800010],go[800010],w[800010];
int henu[200010],nuhe[200010];
bool del[800010],train[800010];
void Add(int x,int y,int k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
void updn(int x){
	for (;x>1&&dist[henu[x]]<dist[henu[x/2]];){
		swap(nuhe[henu[x]],nuhe[henu[x/2]]);
		swap(henu[x],henu[x/2]);
		x=x/2;
	}
	int xx=x<<1;
	for (;xx<=last;){
		if (xx<last&&dist[henu[xx]]>dist[henu[xx+1]])xx++;
		if (dist[henu[xx]]<dist[henu[x]]){
			swap(nuhe[henu[x]],nuhe[henu[xx]]);
			swap(henu[x],henu[xx]);
			x=xx;xx=x<<1;
		}else break;
	}
}
void Del(int x){
	swap(nuhe[henu[1]],nuhe[henu[last]]);
	swap(henu[1],henu[last]);
	last--;
	updn(1);
}
void Init(int data){
	henu[++last]=data;
	nuhe[data]=last;
	updn(last);
}
int main(){
	scanf("%d%d%d",&N,&M,&K);
	for (int i=1;i<=M;i++)scanf("%d%d%d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (int i=1;i<=K;i++)scanf("%d%d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;
	for (int i=1;i<=N;i++)Init(i);
	for (int i=1;i<=N;i++){
		int x=henu[1];Del(1);
		for (int j=st[x];j;j=ne[j])
		if (dist[go[j]]>dist[x]+w[j]){
			dist[go[j]]=dist[x]+w[j];
			updn(nuhe[go[j]]);
		}
	}

	for (int i=1;i<=N;i++)
	for (int j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (int j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (int j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		if (r>20000010){
			printf("= =");
			return 0;
		}
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
int N,M,K,x,y,k,ans,l,r,pt;
bool vis[100010];
int q[10000010];
int dist[100010];
int st[600010],ne[600010],go[600010],w[600010];
void Add(int x,int y,int k){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;}
int main(){
	scanf("%d%d%d",&N,&M,&K);
	for (int i=1;i<=M;i++)scanf("%d%d%d",&x,&y,&k),Add(x,y,k),Add(y,x,k);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		int x=q[l];vis[x]=false;
		for (int i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (int i=1;i<=K;i++){
		scanf("%d%d",&y,&k);
		if (dist[y]<=k)ans++;
	}
	printf("%d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[2000010];
LL dist[2000010],in[2000010];
LL st[2000010],ne[8000010],go[8000010],w[8000010];
bool del[8000010],train[8000010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	if (pt>800010){
		printf("pt:%d\n",pt);
		return 0;
	}
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	if (pt>800010){
		printf("pt:%d\n",pt);
		return 0;
	}
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		if (max(l,r)>20000000){
			printf("r:%d\n",r);
			return 0;
		}
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;q[1]=1;vis[1]=true;
	for (l=0,r=1;l!=r;){
		LL x=q[++l];
		if (l>=N)l-=N;
		vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				++r;if (r>=N)r-=N;
				if (l==r){
					printf("= =");
					return 0;
				}
				q[r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		if (r>20000010)
		printf("= =");
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0),in[x]++,in[y]++;
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1),in[x]++,in[y]++;
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (abs(dist[i]-dist[go[j]])<w[j]){
		del[j]=true;
		in[i]--;in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&abs(dist[go[j]]-dist[1])<=w[j]&&in[1]>1&&in[go[j]]>1){
		del[j]=true;
		in[1]--;in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	if (pt>800010){
		printf("pt:%d\n",pt);
		return 0;
	}
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	if (pt>800010){
		printf("pt:%d\n",pt);
		return 0;
	}
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		if (max(l,r)>20000000){
			printf("r:%d\n",r);
			return 0;
		}
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;q[0]=1;vis[1]=true;
	for (l=0,r=1;l!=r;){
		LL x=q[l];
		l++;if (l>=N)l-=N;
		vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[r]=go[i];
				++r;
				if (r>=N)r-=N;
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <ctime>
#include <cmath>
#include <algorithm>
#define LL long long
using namespace std;
LL N,M,K,x,y,k,pt,l,r,ans;
LL q[20000010],vis[200010];
LL dist[200010],in[200010];
LL st[200010],ne[800010],go[800010],w[800010];
bool del[800010],train[800010];
void Add(LL x,LL y,LL k,bool flag){ne[++pt]=st[x];st[x]=pt;go[pt]=y;w[pt]=k;train[pt]=flag;}
int main(){
	scanf("%I64d%I64d%I64d",&N,&M,&K);
	for (LL i=1;i<=M;i++)scanf("%I64d%I64d%I64d",&x,&y,&k),Add(x,y,k,0),Add(y,x,k,0);
	for (LL i=1;i<=K;i++)scanf("%I64d%I64d",&y,&k),x=1,Add(x,y,k,1),Add(y,x,k,1);
	memset(dist,62,sizeof(dist));
	dist[1]=0;vis[1]=true;
	for (q[l=r=0]=1;l<=r;l++){
		LL x=q[l];vis[x]=false;
		for (LL i=st[x];i;i=ne[i])
		if (dist[go[i]]>dist[x]+w[i]){
			dist[go[i]]=dist[x]+w[i];
			if (!vis[go[i]]){
				q[++r]=go[i];
				vis[go[i]]=true;
			}
		}
	}
	for (LL i=1;i<=N;i++)
	for (LL j=st[i];j;j=ne[j])
	if (dist[i]+w[j]==dist[go[j]])in[go[j]]++;
	else del[j]=true;
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&!del[j]&&dist[go[j]]==w[j]&&in[go[j]]>1){
		del[j]=true;
		in[go[j]]--;
	}
	for (LL j=st[1];j;j=ne[j])
	if (train[j]&&del[j])ans++;
	printf("%I64d",ans);
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        else if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    return 0;
    cout << res << endl;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
struct  canh{
    int x, y, w;
};
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int o = 100 * 1000 * 1000;
const long long oo = 1ll * o * o;
int n, m, k, res;
int degree[MAXN];
long long d[MAXN];
bool visited[MAXN], indis[MAXK + MAXM];
vector < pair<int, int> > e[MAXN];
canh ee[MAXK + MAXM];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = oo;
    reset(visited, false);
    reset(degree, 0);
    reset(indis, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair <int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + 1ll*w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        ee[i + m].x = x; ee[i + m].y = y; ee[i + m].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//--------------------------------------------------------------------
void solution()
{
    FOR(i, 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] == d[y] + 1ll * w || d[y] == d[x] + 1ll * w){
            indis[i] = true;
            degree[x] ++; degree[y]++;
        }
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[i] == false)
            res++;
        else if (degree[x] > 1 && degree[y] > 1){
            res++;
            degree[x]--;
            degree[y]--;
        }
    }
}
//--------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    solution();
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const long long o = 1000 * 1000 * 100;
const long long oo = o * o;
int n, m, k, res;
long long d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <long long, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        else if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(- (long long) w, v));
            else
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    cout << res << endl;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        int tw = -edge_u.first;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
struct  canh{
    int x, y, w;
};
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int o = 100 * 1000 * 1000;
const long long oo = 1ll * o * o;
int n, m, k, res;
int degree[MAXN];
long long d[MAXN];
bool visited[MAXN], indis[MAXK + MAXM];
vector < pair<int, int> > e[MAXN];
canh ee[MAXK + MAXM];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = oo;
    reset(visited, false);
    reset(degree, 0);
    reset(indis, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair <int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + 1ll*w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, m +  1, m + k){
        cin >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//--------------------------------------------------------------------
void solution()
{
    /*FOR(i, 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] == d[y] + 1ll * w || d[y] == d[x] + 1ll * w){
            indis[i] = true;
            degree[x] ++; degree[y]++;
        }
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[i] == false)
            res++;
        else if (degree[x] > 1 && degree[y] > 1){
            res++;
            degree[x]--;
            degree[y]--;
        }
    }*/
    bool viewed[MAXN] = { false };
    FOR(i, 1, m){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] > d[y]){
            if (d[x] == d[y] + w) indis[x] = true;
        }
        else if (d[y] == d[x] + w) indis[y] = true;
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[y] || d[y] < w || viewed[y])
            ++res;
        else viewed[y] = true;
    }
}
//--------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    //FOR(i, 1, n) cout << d[i] << endl;
    solution();
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int oo = 1000 * 1000 * 1000 + 1;
struct canh{
    int x, y, w;
};
vector <int> heap(NULL, NULL);
int n, m, k;
int link[2 * MAXM], d[MAXN], head[MAXN];
bool danhdau[MAXN], pos[MAXN];
canh e[2 * MAXM];
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
bool cmp(int a, int b)
{
    if (d[a] > d[b])
        return true;
    return false;
}
//---------------------------------------------------------------------
void push(int i)
{
    if (pos[i] == false){
        pos[i] == true;
        heap.push_back(i);
        push_heap(heap.begin(), heap.end(), cmp);
    }
    else make_heap(heap.begin(), heap.end(), cmp);
}
//---------------------------------------------------------------------
int pop()
{
    int i = heap.front();
    pop_heap(heap.begin(), heap.end(), cmp);
    heap.pop_back();
    danhdau[i] = true;
    return i;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n)    d[i] = oo;
    reset(danhdau, false);
    reset(pos, false);
    make_heap(heap.begin(), heap.end(), cmp);
}
//---------------------------------------------------------------------
void dijkstra()
{
    d[1] = 0;
    push(1);
    while (heap.empty() == false){
        int u = pop();
        int i = head[u];
        while (i != 0){
            int v = e[i].y;
            if (d[v] > d[u] + e[i].w && danhdau[v] == false){
                d[v] = d[u] + e[i].w;
                push(v);
            }
            i = link[i];
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    FOR(i, 1, m)    cin >> e[i].x >> e[i].y >> e[i].w;
    FOR(i, 1, m)    e[i + m] = e[i];
    reset(head, 0);
    FOR(i, 1, m * 2){
        int x = e[i].x;
        link[i] = head[x];
        head[x] = i;
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra();
    /*FOR(i, 1, n)  cout << d[i] << " ";
    cout << endl;*/
    int res = 0, finish, distance;
    FOR(i, 1, k){
        cin >> finish >> distance;
        if ( d[finish] >= distance ) res ++;
    }
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int o = 100 * 1000 * 1000;
const long long oo = 1ll * o * o;
struct canh{
    int x, y, w;
};
int n, m, k, res;
long long d[MAXN];
bool visited[MAXN];
canh edge[MAXK];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair <int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + 1ll*w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    FOR(i, 1, k){
        int x = 1, y, z;
        cin >> y >> z;
        if (z >= d[y])
            res++;
    }
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        else if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    cout << res << endl;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        else if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    return 0;
    dijkstra(1);
    cout << res << endl;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
struct  canh{
    int x, y, w;
};
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int o = 100 * 1000 * 1000;
const long long oo = 1ll * o * o;
int n, m, k, res;
int degree[MAXN];
long long d[MAXN];
bool visited[MAXN], indis[MAXK + MAXM];
vector < pair<int, int> > e[MAXN];
canh ee[MAXK + MAXM];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = oo;
    reset(visited, false);
    reset(degree, 0);
    reset(indis, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if ( visited[u] == true ) continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair <int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + 1ll*w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, m +  1, m + k){
        cin >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//--------------------------------------------------------------------
void solution()
{
    /*FOR(i, 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] == d[y] + 1ll * w || d[y] == d[x] + 1ll * w){
            indis[i] = true;
            degree[x] ++; degree[y]++;
        }
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[i] == false)
            res++;
        else if (degree[x] > 1 && degree[y] > 1){
            res++;
            degree[x]--;
            degree[y]--;
        }
    }*/
    bool viewed[MAXN] = { false };
    FOR(i, 1, m){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] > d[y]){
            if (d[x] == d[y] + w) indis[x] = true;
        }
        else if (d[y] == d[x] + w) indis[y] = true;
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[y] || d[y] < w || viewed[y])
            ++res;
        else viewed[y] = true;
    }
}
//--------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    //FOR(i, 1, n) cout << d[i] << endl;
    solution();
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        int tw = -edge_u.first;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
struct  canh{
    int x, y, w;
};
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int MAXK = MAXN;
const int o = 100 * 1000 * 1000;
const long long oo = 1ll * o * o;
int n, m, k, res;
int degree[MAXN];
long long d[MAXN];
bool visited[MAXN], indis[MAXK + MAXM];
vector < pair<int, int> > e[MAXN];
canh ee[MAXK + MAXM];
priority_queue < pair<long long, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = oo;
    reset(visited, false);
    reset(degree, 0);
    reset(indis, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0ll;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        long long tw = -edge_u.first;
        if ( tw != d[u] ) continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair <int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (d[v] > d[u] + 1ll*w && visited[v] == false){
                d[v] = d[u] + 1ll*w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, m +  1, m + k){
        cin >> y >> z;
        ee[i].x = x; ee[i].y = y; ee[i].w = z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//--------------------------------------------------------------------
void solution()
{
    /*FOR(i, 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] == d[y] + 1ll * w || d[y] == d[x] + 1ll * w){
            indis[i] = true;
            degree[x] ++; degree[y]++;
        }
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[i] == false)
            res++;
        else if (degree[x] > 1 && degree[y] > 1){
            res++;
            degree[x]--;
            degree[y]--;
        }
    }*/
    bool viewed[MAXN] = { false };
    FOR(i, 1, m){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (d[x] > d[y]){
            if (d[x] == d[y] + w) indis[x] = true;
        }
        else if (d[y] == d[x] + w) indis[y] = true;
    }
    FOR(i, m + 1, m + k){
        int x = ee[i].x, y = ee[i].y, w = ee[i].w;
        if (indis[y] || d[y] < w || viewed[y])
            ++res;
        else viewed[y] = true;
    }
}
//--------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    //FOR(i, 1, n) cout << d[i] << endl;
    solution();
    cout << res;
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
#include <string>
#include <map>
#include <set>
#include <list>
#include <deque>
#define FOR(i,a,b) for (int i=(a),_b=(b);i<=_b;i++)
#define DOWFOR(i,a,b) for (int i=(a),_b=(b);i>=_b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define reset(c,x) memset(c,x,sizeof(c))
using namespace std;
//---------------------------------------------------------------------
const int MAXM = 3 * 100 * 1000 + 1;
const int MAXN = 100 * 1000 + 1;
const int oo = 1000 * 1000 * 1000 + 1;
int n, m, k, res;
int d[MAXN];
bool visited[MAXN];
vector < pair<int, int> > e[MAXN];
priority_queue < pair<int, int> > dheap;
//-------------------------------------------------------------------
int gcd(int xx, int yy) // greatest common divisor
{
    while (yy != 0)
    {
        xx = xx%yy;
        swap(xx, yy);
    }
    return xx;
}
//-------------------------------------------------------------------
int lcm(int xx, int yy) // least common mutiple
{
    return (xx / gcd(xx, yy))*yy;
}
//---------------------------------------------------------------------
void Init()
{
    FOR(i, 1, n) d[i] = +oo;
    reset(visited, false);
    res = 0;
}
//---------------------------------------------------------------------
void dijkstra(int start)
{
    d[start] = 0;
    dheap.push(make_pair(-d[start], start));
    while (dheap.empty() == false){
        pair <int, int> edge_u = dheap.top(); dheap.pop();
        int u = edge_u.second;
        if (u < 0){
            u = -u;
            if (visited[u] == true){
                res++;
                continue;
            }
        }
        else if (visited[u] == true)
            continue;
        visited[u] = true;
        FOR(i, 0, e[u].size() - 1){
            pair<int, int> edge_v = e[u][i];
            int v = edge_v.first, w = edge_v.second;
            if (v <= 0)
                dheap.push(make_pair(-w, v));
            else
            if (d[v] > d[u] + w && visited[v] == false){
                d[v] = d[u] + w;
                dheap.push(make_pair(-d[v], v));
            }
        }
    }
}
//---------------------------------------------------------------------
void Read_Input()
{
    cin >> n >> m >> k;
    int x, y, z;
    FOR(i, 1, m){
        cin >> x >> y >> z;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
    x = 1;
    FOR(i, 1, k){
        cin >> y >> z;
        y = -y;
        e[x].push_back(make_pair(y, z));
        e[y].push_back(make_pair(x, z));
    }
}
//---------------------------------------------------------------------
int main()
{
    Read_Input();
    Init();
    dijkstra(1);
    cout << res << endl;
    return 0;
}


#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    unsigned long long d; // shortest distance from capital
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

struct Node
{
    Node(int uu, int vv, int xx, bool track) : u(uu), v(vv), x(xx), bTrack(track) {}
    int u, v, x;
    bool bTrack;
};

bool operator>(const Node& n1, const Node& n2)
{
    if (n1.x != n2.x) return n1.x > n2.x;
    if (n1.u != n2.u) return n1.u > n2.u;
    if (n1.v != n2.v) return n1.v > n2.v;
    return (int)n1.bTrack > (int)n2.bTrack;
}

bool visited[300005];

int main(void)
{
    memset(visited, 0, sizeof(visited));
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    for (int i = 1; i <= n; ++i)
    {
        cities[i].d = (unsigned long long)1 << 63;
    }

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);
        cities[roads[i].u].roads.push_back(i);
        cities[roads[i].v].roads.push_back(i);
    }

    cities[0].d = 0;

    priority_queue<Node, vector<Node>, greater<Node> > pq;
    pq.push(Node(0, 1, 0, false));

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        pq.push(Node(1, s, y, true));
    }

    int usedTrackCount = 0;

    while (!pq.empty())
    {
        Node curNode(pq.top()); pq.pop();
        if (cities[curNode.v].d <= cities[curNode.u].d + (unsigned long long)curNode.x)
            continue;

        if (curNode.bTrack) usedTrackCount++;

        City& city = cities[curNode.v];
        city.d = cities[curNode.u].d + (unsigned long long)curNode.x;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            int ri = *it;
            if (visited[ri]) continue;
            visited[ri] = true;
            const Edge& road = roads[ri];
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            int u = road.u == curNode.v ? road.u : road.v;
            int v = road.u == curNode.v ? road.v : road.u;
            if (otherCityDistanceUsingRoad < cities[v].d)
                pq.push(Node(u, v, road.x, false));
        }
    }

    cout << k - usedTrackCount;// << endl;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

inline bool UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        return true;
    }
    return false;
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    deque<int> dq;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            if (UpdateDistance(oi, (unsigned long long)roads[i].x, false) && !cities[oi].bInQ)
            {
                cities[oi].bInQ = true;
                dq.push_back(oi);
            }
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        if (UpdateDistance(s, (unsigned long long)y, true)  && !cities[s].bInQ)
        {
            cities[s].bInQ = true;
            dq.push_back(s);
        }
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            if (UpdateDistance(oci, otherCityDistanceUsingRoad, false) && !cities[oci].bInQ)
            {
                cities[oci].bInQ = true;
                dq.push_back(oci);
            }
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>
#include <map>

using namespace std;

struct City
{
    unsigned long long d; // shortest distance from capital
    vector<int> roads;
};

City cities[200005];

struct Node
{
    Node(int uu, int vv, int xx, bool track) : u(uu), v(vv), x(xx), bTrack(track) {}
    int u, v, x;
    bool bTrack;
};

bool operator>(const Node& n1, const Node& n2)
{
    if (n1.x != n2.x) return n1.x > n2.x;
    if (n1.u != n2.u) return n1.u > n2.u;
    if (n1.v != n2.v) return n1.v > n2.v;
    return (int)n1.bTrack > (int)n2.bTrack;
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    for (int i = 1; i <= n; ++i)
    {
        cities[i].d = (unsigned long long)1 << 63;
    }

    map<pair<int, int>, int> sii;

    for (int i = 0; i < m; ++i)
    {
        int u, v, x;
        fscanf(stdin, "%d %d %d", &u, &v, &x);
        if (u > v) swap(u, v);
        pair<int, int> rp = make_pair(u, v);
        map<pair<int, int>, int>::iterator itFind = sii.find(rp);

        if (itFind == sii.end())
        {
            sii[rp] = x;
            cities[u].roads.push_back(v);
            cities[v].roads.push_back(u);
        }
        else
        {
            itFind->second = min(itFind->second, x);
        }
    }

    cities[0].d = 0;

    priority_queue<Node, vector<Node>, greater<Node> > pq;
    pq.push(Node(0, 1, 0, false));

    map<int, int> tii;

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        map<int, int>::iterator itFind = tii.find(s);
        if (itFind == tii.end())
        {
            tii[s] = y;
        }
        else
        {
            itFind->second = min(itFind->second, y);
        }
    }

    for (map<int, int>::const_iterator itt(tii.begin()), ittEnd(tii.end()); itt != ittEnd; ++itt)
        pq.push(Node(1, itt->first, itt->second, true));

    int usedTrackCount = 0;

    while (!pq.empty())
    {
        Node curNode(pq.top()); pq.pop();
        if (cities[curNode.v].d <= cities[curNode.u].d + (unsigned long long)curNode.x)
            continue;

        if (curNode.bTrack) usedTrackCount++;

        City& city = cities[curNode.v];
        city.d = cities[curNode.u].d + (unsigned long long)curNode.x;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            int otherCity = *it;
            map<pair<int, int>, int>::iterator itFind = sii.find(make_pair(min(curNode.v, otherCity), max(curNode.v, otherCity)));
            if (itFind != sii.end())
            {
                unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)itFind->second;
                int u = curNode.v;
                int v = otherCity;
                if (otherCityDistanceUsingRoad < cities[v].d)
                    pq.push(Node(u, v, itFind->second, false));
                sii.erase(itFind); // erase the road from u,v
            }
        }
    }

    cout << k - usedTrackCount;// << endl;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

deque<int> dq;

// SPFA Algorithm
inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        if (!cities[ci].bInQ)
        {
            cities[ci].bInQ = true;
            if (d < dq.front()) dq.push_front(ci);
            else dq.push_back(ci);
        }
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            UpdateDistance(oi, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

deque<int> dq;

// SPFA Algorithm
inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        if (!cities[ci].bInQ)
        {
            cities[ci].bInQ = true;
            dq.push_back(ci);
        }
        if (dq.back() < dq.front()) (dq.front(), dq.back());  // small label first optimization SLF
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            UpdateDistance(oi, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

deque<int> dq;
unsigned long long total = 0;

// SPFA Algorithm
inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        unsigned long long oldDist = cities[ci].d;
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        if (!cities[ci].bInQ)
        {
            total += d;
            cities[ci].bInQ = true;
            if (!dq.empty() && d < cities[dq.front()].d) dq.push_front(ci); // Small Label First Optimization
            else dq.push_back(ci);
        }
        else total = total - oldDist + d;

        unsigned long long avg = total / dq.size(); // Large Label Last Optimization
        while (cities[dq.front()].d > avg)
        {
            int idx = dq.front(); dq.pop_front();
            dq.push_back(idx);
        }
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            UpdateDistance(oi, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;
        total -= cities[ci].d;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    unsigned long long d; // shortest distance from capital
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

struct Node
{
    Node(int uu, int vv, int xx, bool track) : u(uu), v(vv), x(xx), bTrack(track) {}
    int u, v, x;
    bool bTrack;
};

bool operator>(const Node& n1, const Node& n2)
{
    if (n1.x != n2.x) return n1.x > n2.x;
    if (n1.u != n2.u) return n1.u > n2.u;
    if (n1.v != n2.v) return n1.v > n2.v;
    return (int)n1.bTrack > (int)n2.bTrack;
}

bool visited[100005];

int main(void)
{
    memset(visited, 0, sizeof(visited));
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    for (int i = 1; i <= n; ++i)
    {
        cities[i].d = (unsigned long long)1 << 63;
    }

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);
        cities[roads[i].u].roads.push_back(i);
        cities[roads[i].v].roads.push_back(i);
    }

    cities[0].d = 0;

    priority_queue<Node, vector<Node>, greater<Node> > pq;
    pq.push(Node(0, 1, 0, false));

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        pq.push(Node(1, s, y, true));
    }

    int usedTrackCount = 0;
    int visitCount = 0;

    while (!pq.empty())
    {
        Node curNode(pq.top()); pq.pop();
        if (cities[curNode.v].d <= cities[curNode.u].d + (unsigned long long)curNode.x)
            continue;

        if (curNode.bTrack) usedTrackCount++;

        City& city = cities[curNode.v];
        city.d = cities[curNode.u].d + (unsigned long long)curNode.x;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            int u = curNode.v;
            int v = road.u == curNode.v ? road.v : road.u;
            if (!visited[v] && otherCityDistanceUsingRoad < cities[v].d)
                pq.push(Node(u, v, road.x, false));
        }

        visited[curNode.v] = true;
        if (++visitCount == n) break;
    }

    cout << k - usedTrackCount;// << endl;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

deque<int> dq;

// SPFA Algorithm
inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        if (!cities[ci].bInQ)
        {
            cities[ci].bInQ = true;
            if (!dq.empty() && d < dq.front()) dq.push_front(ci);
            else dq.push_back(ci);
        }
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            UpdateDistance(oi, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    unsigned long long d; // shortest distance from capital
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

struct Node
{
    Node(int uu, int vv, int xx, bool track) : u(uu), v(vv), x(xx), bTrack(track) {}
    int u, v, x;
    bool bTrack;
};

bool operator>(const Node& n1, const Node& n2)
{
    if (n1.x != n2.x) return n1.x > n2.x;
    if (n1.u != n2.u) return n1.u > n2.u;
    if (n1.v != n2.v) return n1.v > n2.v;
    return (int)n1.bTrack > (int)n2.bTrack;
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    for (int i = 1; i <= n; ++i)
    {
        cities[i].d = (unsigned long long)1 << 63;
    }

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);
        cities[roads[i].u].roads.push_back(i);
        cities[roads[i].v].roads.push_back(i);
    }

    cities[0].d = 0;

    priority_queue<Node, vector<Node>, greater<Node> > pq;
    pq.push(Node(0, 1, 0, false));

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        pq.push(Node(1, s, y, true));
    }

    int usedTrackCount = 0;

    while (!pq.empty())
    {
        Node curNode(pq.top()); pq.pop();
        if (cities[curNode.v].d <= cities[curNode.u].d + (unsigned long long)curNode.x)
            continue;

        if (curNode.bTrack) usedTrackCount++;

        City& city = cities[curNode.v];
        city.d = cities[curNode.u].d + (unsigned long long)curNode.x;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            int u = road.u == curNode.v ? road.u : road.v;
            int v = road.u == curNode.v ? road.v : road.u;
            if (otherCityDistanceUsingRoad < cities[v].d)
                pq.push(Node(u, v, road.x, false));
        }
    }

    cout << k - usedTrackCount;// << endl;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

inline bool UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        return true;
    }
    return false;
}

int main(void)
{
    freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    deque<int> dq;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            if (UpdateDistance(oi, (unsigned long long)roads[i].x, false) && !cities[oi].bInQ)
            {
                cities[oi].bInQ = true;
                dq.push_back(oi);
            }
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        if (UpdateDistance(s, (unsigned long long)y, true)  && !cities[s].bInQ)
        {
            cities[s].bInQ = true;
            dq.push_back(s);
        }
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            if (UpdateDistance(oci, otherCityDistanceUsingRoad, false) && !cities[oci].bInQ)
            {
                cities[oci].bInQ = true;
                dq.push_back(oci);
            }
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    unsigned long long d; // shortest distance from capital
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

struct Node
{
    Node()  {}
    Node(int uu, int vv, int xx, bool track) : u(uu), v(vv), x(xx), bTrack(track) {}
    int u, v, x;
    bool bTrack;
};

bool operator>(const Node& n1, const Node& n2)
{
    if (n1.x != n2.x) return n1.x > n2.x;
    if (n1.u != n2.u) return n1.u > n2.u;
    if (n1.v != n2.v) return n1.v > n2.v;
    return (int)n1.bTrack > (int)n2.bTrack;
}

Node tracks[100005];

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    for (int i = 1; i <= n; ++i)
    {
        cities[i].d = (unsigned long long)1 << 63;
    }

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);
        cities[roads[i].u].roads.push_back(i);
        cities[roads[i].v].roads.push_back(i);
    }

    cities[0].d = 0;

    tracks[0] = Node(0, 1, 0, false);
    for (int i = 1; i <= k; ++i)
    {
        tracks[i].u = 1;
        fscanf(stdin, "%d %d", &tracks[i].v, &tracks[i].x);
        tracks[i].bTrack = true;
    }

    priority_queue<Node, vector<Node>, greater<Node> > pq(tracks, tracks+k+1);

    int usedTrackCount = 0;

    while (!pq.empty())
    {
        Node curNode(pq.top()); pq.pop();
        if (cities[curNode.v].d <= cities[curNode.u].d + (unsigned long long)curNode.x)
            continue;

        if (curNode.bTrack) usedTrackCount++;

        City& city = cities[curNode.v];
        city.d = cities[curNode.u].d + (unsigned long long)curNode.x;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            int u = road.u == curNode.v ? road.u : road.v;
            int v = road.u == curNode.v ? road.v : road.u;
            if (otherCityDistanceUsingRoad < cities[v].d)
                pq.push(Node(u, v, road.x, false));
        }
    }

    cout << k - usedTrackCount;// << endl;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>
#include <set>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bVisited(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bVisited;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

bool LessThan(int i, int j)
{
    City& ci = cities[i];
    City& cj = cities[j];

    if (ci.d != cj.d) return ci.d < cj.d;
    if (ci.bPrevTrack != cj.bPrevTrack) return ci.bPrevTrack;
    if (i != j) return i < j;
    return false;
}

std::set<int,bool(*)(int,int)> pq (LessThan);  // function pointer as Compare

inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        pq.erase(ci);
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        pq.insert(ci);
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 1; i <= n; ++i) pq.insert(i);

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            UpdateDistance(roads[i].u == 1 ? roads[i].v : roads[i].u, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!pq.empty())
    {
        int ci = *(pq.begin());
        pq.erase(ci);
        City& city = cities[ci];
        city.bVisited = true;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            if (cities[oci].bVisited) continue;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}


#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

struct City
{
    City() : d((unsigned long long)1 << 63), prev(0), bPrevTrack(false), bInQ(false) {}
    unsigned long long d; // shortest distance from capital
    int prev;
    bool bPrevTrack;
    bool bInQ;
    vector<int> roads;
};

struct Edge
{
    int u, v, x;
};

City cities[200005];
Edge roads[300005];

deque<int> dq;

// SPFA Algorithm
inline void UpdateDistance(int ci, unsigned long long d, bool bTrack)
{
    if ((d < cities[ci].d) || (d == cities[ci].d && cities[ci].bPrevTrack && !bTrack))
    {
        cities[ci].d = d;
        cities[ci].bPrevTrack = bTrack;
        if (!cities[ci].bInQ)
        {
            cities[ci].bInQ = true;
            if (!dq.empty() && d < cities[dq.front()].d) dq.push_front(ci);
            else dq.push_back(ci);
        }
    }
}

int main(void)
{
    //freopen("data.txt", "r", stdin);
    int n, m, k;
    fscanf(stdin, "%d %d %d", &n, &m, &k);

    City& capitol = cities[1];
    capitol.d = 0;

    for (int i = 0; i < m; ++i)
    {
        fscanf(stdin, "%d %d %d", &roads[i].u, &roads[i].v, &roads[i].x);

        if (roads[i].u == 1 || roads[i].v == 1)
        {
            int oi = roads[i].u == 1 ? roads[i].v : roads[i].u;
            UpdateDistance(oi, (unsigned long long)roads[i].x, false);
        }
        else
        {
            cities[roads[i].u].roads.push_back(i);
            cities[roads[i].v].roads.push_back(i);
        }
    }

    for (int i = 0; i < k; ++i)
    {
        int s, y;
        fscanf(stdin, "%d %d", &s, &y);
        UpdateDistance(s, (unsigned long long)y, true);
    }

    while (!dq.empty())
    {
        int ci = dq.front(); dq.pop_front();
        City& city = cities[ci];
        city.bInQ = false;

        for (vector<int>::const_iterator it(city.roads.begin()), itEnd(city.roads.end()); it != itEnd; ++it)
        {
            const Edge& road = roads[*it];
            int oci = road.u == ci ? road.v : road.u;
            unsigned long long otherCityDistanceUsingRoad = city.d + (unsigned long long)road.x;
            UpdateDistance(oci, otherCityDistanceUsingRoad, false);
        }
    }

    int usedTrackCount = 0;
    for (int i = 2; i <= n; ++i) if (cities[i].bPrevTrack) usedTrackCount++;
    cout << k - usedTrackCount;
}