from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
l.sort(reverse=True)
a = l[:n] ; b = l[n:]; m= 0
debug(a , b)
k =0
for i in range(n):
    if a[k] > b[k] :m+=1
    elif a[k]==b[k]:pass
    else:m-=1
    k+=1
print("YES") if m>0 else print("NO")


from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
l.sort(reverse=True)
a = l[:n] ; b = l[n:]; m= 0
debug(a , b)
k =0
for i in range(n):
    if a[k] > b[k] :m+=1
    else:m-=1
    k+=1
print("YES") if m>0 else print("NO")


from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
a = l[:n] ; b = l[n:]; m= 0
a.sort(reverse=True) ; b.sort(reverse=True)
debug(a , b)
k =0
for i in range(n):
    if a[k] > b[k] :m+=1
    elif a[k]==b[k]:pass
    else:m-=1
    k+=1
print("YES") if m>0 else print("NO")


from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
l.sort()
if l[n-1] < l[n]:print("YES")
else:print("NO")


from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
l.sort()
if l[n] < l[n-1]:print("YES")
else:print("NO")


from sys import maxsize, stdout, stdin,stderr
mod = int(1e9 + 7)
import re #can use multiple splits
def tup():return map(int,stdin.readline().split())
def I(): return int(stdin.readline())
def lint(): return [int(x) for x in stdin.readline().split()]
def S(): return input().strip()
def grid(r, c): return [lint() for i in range(r)]
def debug(*args, c=6): print('\033[3{}m'.format(c), *args, '\033[0m', file=stderr)
from  math import  log2,sqrt
n = I()
l =lint()
l.sort(reverse=True)
a = l[:n] ; b = l[n:]; m= 0
debug(a , b)
k =0
for i in range(n):
    if a[k] in b:m= -1;break
    if a[k] > b[k]:m+=1
    else:m-=1
    k+=1
print("YES") if m>0 else print("NO")


n=int(input())
t=list(map(int,input().split()))
t=sorted(t)
if t[n]==t[n-1]:print('NO')
else:print('YES')


n=int(input())
t=list(map(int,input().split()))
t=sorted(t)
if t[n//2]==t[n//2-1]:print('NO')
else:print('YES')


a = int(input())
b = a*2
c = input()
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  print(s)
  x = 0
  for i in f:
      if i > s:
          x += 1
  if x == a:
      return 'Yes'

  return 'No'

print(resitev())


a = int(input())
b = a*2
c = input()
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  x = 0
  for i in f:
      if i > s:
          x += 1
  if x >= a//2:
      return 'Yes'

  return 'No'

print(resitev())


a = int(input())
b = a*2
c = input()
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  x = 0
  for i in f:
      if i > s:
          x += 1
  if x == a:
      return 'Yes'

  return 'No'

print(resitev())


a = int(input())
b = a*2
c = input()
print(c)
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
print(c)
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  x = 0
  for i in f:
      if i > s:
          x += 1
  print(x,s,a//2)
  if x > a//2:
      return 'Yes'

  return 'No'

print(resitev())


a = int(input())
b = a*2
c = input()
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  x = 0
  for i in f:
      if i > s:
          x += 1
  if x > a//2:
      return 'Yes'

  return 'No'

print(resitev())


a = int(input())
b = a*2
c = input()
c = [c]
c = c[0].split(' ')
for i in range(len(c)):
    c[i] = int(c[i])
def resitev():
  d = sorted(c)
  f = d[a:2*a]
  s = d[a-1]
  x = 0
  for i in f:
      if i > s:
          x += 1
  if x > a//2:
      return 'Yes'

  return 'No'

resitev()


#include<cstdio>
#include<vector>
using namespace std;

const int maxn = 100001;
typedef long long ll;
struct Rou {
  int v;
  ll l;
};
vector<Rou> rou[maxn];
int n, m, k, y[maxn], s[maxn], stack[maxn], in[maxn];
ll opt[maxn];
bool used[maxn];
bool Check(ll &x, ll y) {
  if (x<0 || y<x) {
    x = y;
    return 1;
  }
  return 0;
}
Rou MK(int v, int l) {
  Rou tmp;
  tmp.v = v;
  tmp.l = l;
  return tmp;
}
void SPFA() {
  int l = 0, r, u;
  stack[0] = r = 1, used[1] = 1;
  while (l != r) {
    u = stack[l];
    for (int i = 0; i < rou[u].size(); i++)
      if (Check(opt[rou[u][i].v], opt[u]+rou[u][i].l) && !used[rou[u][i].v]) {
        stack[r] = rou[u][i].v;
        used[rou[u][i].v] = 1;
        r = (r+1)%maxn;
      }
    used[u] = 0;
    l = (l+1)%maxn;
  }
}
int main()
{
  scanf("%d%d%d", &n, &m, &k);
  int u, v, x, ans = 0;
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 2; i <= n; i++) opt[i] = -1;
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &s[i], &y[i]);
    rou[1].push_back(MK(s[i], y[i]));
  }
  SPFA();
  for (int u = 1; u <= n; u++)
    for (int i = 0; i < rou[u].size(); i++)
      if (opt[u]+rou[u][i].l == opt[rou[u][i].v]) in[rou[u][i].v]++;
  for (int i = 0; i < k; i++)
    if (opt[s[i]] < y[i]) {
      ans++;
    } else {
      if (in[s[i]] > 1) {
        in[s[i]]--;
        ans++;
      }
    }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
}
void Delete(int u) {
  if (u > tot) return;
  swap(tree[tot], tree[u]);
  l[tree[u].v] = u;
  l[tree[tot].v] = tot--;
  Move(u);
  Maintain(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
int n, m, k, tot, l[maxn], opt[maxn];
struct Route {
  int v, l, id;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m].l, tree[u].l);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &t[i].l);
    t[i].id = i;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0U>>1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      used[t[now].id] = 1;
      v = t[now++].v;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++) {
      tt = l[rou[v][i].v];
      tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
      Maintain(tt);
    }
  }
  int ans = 0;
  for (int i = 0; i < k; i++)
    if (!used[i]) ans++;
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v, id;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
    t[i].id = i;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0U>>1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      used[t[now].id] = 1;
      v = t[now++].v;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] == 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  int ans = 0;
  for (int i = 0; i < k; i++)
    if (!used[i]) ans++;
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    l[i] = i-1;
    opt[i] = -1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] == 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  if (u > tot) return;
  swap(tree[tot], tree[u]);
  l[tree[u].v] = u;
  l[tree[tot].v] = tot--;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 1e5+1;
int n, m, k, tot, l[maxn], opt[maxn];
struct Route {
  int v, l, id;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m].l, tree[u].l);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &t[i].l);
    t[i].id = i;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0U>>1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      used[t[now].id] = 1;
      v = t[now].v;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++) {
      tt = l[rou[v][i].v];
      tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
      Maintain(tt);
    }
  }
  int ans = 0;
  for (int i = 0; i < k; i++)
    if (!used[i]) ans++;
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
  Maintain(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] == 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  Maintain(u);
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
}
void Delete(int u) {
  if (u > tot) return;
  swap(tree[tot], tree[u]);
  l[tree[u].v] = u;
  l[tree[tot].v] = tot--;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v, id;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m].l, tree[u].l);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
  Maintain(u);
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
    t[i].id = i;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0U>>1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      used[t[now].id] = 1;
      v = t[now++].v;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] == 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  int ans = 0;
  for (int i = 0; i < k; i++)
    if (!used[i]) ans++;
  printf("%d\n", ans);
}


#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn = 200000;
typedef long long ll;
int n, m, k, tot, l[maxn];
ll opt[maxn];
struct Route {
  int v;
  ll l;
} t[maxn], tree[maxn];
vector<Route> rou[maxn];
bool used[maxn];
Route MK(int x, int y) {
  Route tmp;
  tmp.v = x;
  tmp.l = y;
  return tmp;
}
bool cmp(Route x, Route y) { return x.l<y.l; }
Route HeapTop() { return tree[1]; }
void Maintain(int u) {
  if (u>1 && tree[u].l<tree[(u>>1)].l) {
    swap(tree[u], tree[(u>>1)]);
    l[tree[u].v] = u;
    l[tree[u>>1].v] = u>>1;
    Maintain(u>>1);
  }
}
void Move(int u) {
  int ll = u<<1, r = (u<<1)+1, m = ll;
  if (ll > tot) return;
  if (r<=tot && tree[r].l<tree[ll].l) m = r;
  if (tree[m].l < tree[u].l) {
    swap(tree[m], tree[u]);
    l[tree[m].v] = m;
    l[tree[u].v] = u;
    Move(m);
  }
}
void Delete(int u) {
  swap(tree[tot--], tree[u]);
  l[tree[u].v] = u;
  Maintain(u);
  Move(u);
}
int main()
{
  int u, v, x;
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 0; i < m; i++) {
    scanf("%d%d%d", &u, &v, &x);
    rou[u].push_back(MK(v, x));
    rou[v].push_back(MK(u, x));
  }
  for (int i = 0; i < k; i++) {
    scanf("%d%d", &t[i].v, &x);
    t[i].l = x;
  }
  sort(t, t+k, cmp);
  for (int i = 2; i <= n; i++) {
    tree[i-1].v = i;
    tree[i-1].l = ~0ULL>>1;
    opt[i] = -1;
    l[i] = i-1;
  }
  tot = n-1;
  int tt, now = 0, ans = k;
  for (int i = 0; i < rou[1].size(); i++) {
    tt = l[rou[1][i].v];
    tree[tt].l = min(tree[tt].l, rou[1][i].l);
    Maintain(tt);
  }
  for (int i = 1; i < n; i++) {
    while (now<k && opt[t[now].v]>=0) now++;
    Route tmp = HeapTop();
    if (now<k && tmp.l>t[now].l) {
      opt[t[now].v] = t[now].l;
      v = t[now++].v;
      ans--;
    } else {
      opt[tmp.v] = tmp.l;
      v = tmp.v;
    }
    Delete(l[v]);
    for (int i = 0; i < rou[v].size(); i++)
      if (opt[rou[v][i].v] < 0) {
        tt = l[rou[v][i].v];
        tree[tt].l = min(tree[tt].l, opt[v]+rou[v][i].l);
        Maintain(tt);
      }
  }
  printf("%d\n", ans);
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <int> val[N];
int dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for (int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,0,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		if (dist[x]==0)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
			dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[1] = true;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==0||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==0) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		//road[x].push_back(y);
		//val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
#include <queue>
#define N 100020
//std::vector <int> road[N];
//std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int H[N];
int n,m,k,ans,cnt;
struct Node
{
	int v,next;
	long long len;
}edge[4*N];
void addedge(int x,int y,long long val)
{
	cnt++;
	edge[cnt].v = y;
	edge[cnt].len = val;
	edge[cnt].next = H[x];
	H[x] = cnt;
}
struct cmp
{
	bool operator() (const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	//memset(road,0,sizeof(road));
	//memset(val,0,sizeof(val));
	memset(H,-1,sizeof(H));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		addedge(x,y,z);
		addedge(y,x,z);
		//road[x].push_back(y);
		//val[x].push_back(z);
		//road[y].push_back(x);
		//val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp>q;
	memset(vist,0,sizeof(vist));
	q.insert(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		for (int i=H[x];i!=-1;i=edge[i].next)
		{
			int y = edge[i].v;
			if (dist[y]==-1||dist[x]+edge[i].len<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + edge[i].len;
				else if (dist[x]+edge[i].len<=dist[y])
				{
					dist[y] = dist[x] + edge[i].len;
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
int n,m,k,ans;
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	dist[1] = 0;
	for (int i=1;i<=n;i++)
	{
		if (dist[i]!=-1)
		{
			//q.push(i);
			q.insert(i);
		}
	}
	while (!q.empty())
	{
		//int x = q.front();
		int x = *q.begin();
		//q.pop();
		q.erase(x);
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					if (dist[x]+val[x][i]<dist[y])
					{
						dist[y] = dist[x] + val[x][i];
						//q.push(y);
						q.insert(y);
					}
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
			}
		}
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
#include <queue>
#define N 100020
//std::vector <int> road[N];
//std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int H[N];
int n,m,k,ans,cnt;
struct Node
{
	int v,next;
	long long len;
}edge[4*N];
void addedge(int x,int y,long long val)
{
	cnt++;
	edge[cnt].v = y;
	edge[cnt].len = val;
	edge[cnt].next = H[x];
	H[x] = cnt;
}
struct cmp
{
	bool operator() (const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	//memset(road,0,sizeof(road));
	//memset(val,0,sizeof(val));
	memset(H,-1,sizeof(H));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		addedge(x,y,z);
		addedge(y,x,z);
		//road[x].push_back(y);
		//val[x].push_back(z);
		//road[y].push_back(x);
		//val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp>q;
	memset(vist,0,sizeof(vist));
	q.insert(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		for (int i=H[x];i!=-1;i=edge[i].next)
		{
			int y = edge[i].v;
			if (dist[y]==-1||(dist[x]+edge[i].len<dist[y])||(dist[x]+edge[i].len==dist[y]&&flag[y]))
			{
				if (dist[y]==-1) dist[y] = dist[x] + edge[i].len;
				else if (dist[x]+edge[i].len<=dist[y])
				{
					dist[y] = dist[x] + edge[i].len;
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
#define INF 100000000
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
//bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	//memset(dist,-1,sizeof(dist));
	for (int i=1;i<=n;i++) dist[i] = INF;
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==INF)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	//memset(vist,0,sizeof(vist));
	dist[1] = 0;
	//for (int i=1;i<=n;i++)
	//{
	//	if (dist[i]!=-1)
	//	{
	//		q.push(i);
	//		vist[i] = true;
	//	}
	//}
	for (int i=1;i<=n;i++) q.insert(i);
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		//q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==INF||dist[x]+val[x][i]<=dist[y])
			{
				q.erase(y);
				dist[y] = dist[x] + val[x][i];
				q.insert(y);
				if (flag[y])
				{
					flag[y] = false;
					ans ++;
				}
				//if (!vist[y])
				//{
				//	vist[y] = true;
				//	q.push(y);
				//}
			}
		}
		//vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
#define INF 1<<60
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
//bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	//memset(dist,-1,sizeof(dist));
	for (int i=1;i<=n;i++) dist[i] = INF;
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==INF)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int> q;
	//memset(vist,0,sizeof(vist));
	dist[1] = 0;
	//for (int i=1;i<=n;i++)
	//{
	//	if (dist[i]!=-1)
	//	{
	//		q.push(i);
	//		vist[i] = true;
	//	}
	//}
	for (int i=1;i<=n;i++) q.insert(i);
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		//q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[x]+val[x][i]<=dist[y])
			{
				q.erase(y);
				dist[y] = dist[x] + val[x][i];
				q.insert(y);
				if (flag[y])
				{
					flag[y] = false;
					ans ++;
				}
				//if (!vist[y])
				//{
				//	vist[y] = true;
				//	q.push(y);
				//}
			}
		}
		//vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
#define INF 1000000000000000
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
//bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	//memset(dist,-1,sizeof(dist));
	for (int i=1;i<=n;i++) dist[i] = INF;
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==INF)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	//memset(vist,0,sizeof(vist));
	dist[1] = 0;
	//for (int i=1;i<=n;i++)
	//{
	//	if (dist[i]!=-1)
	//	{
	//		q.push(i);
	//		vist[i] = true;
	//	}
	//}
	for (int i=1;i<=n;i++) q.insert(i);
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		//q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==INF||dist[x]+val[x][i]<=dist[y])
			{
				q.erase(y);
				dist[y] = dist[x] + val[x][i];
				q.insert(y);
				if (flag[y])
				{
					flag[y] = false;
					ans ++;
				}
				//if (!vist[y])
				//{
				//	vist[y] = true;
				//	q.push(y);
				//}
			}
		}
		//vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	dist[1] = 0;
	for (int i=1;i<=n;i++)
	{
		if (dist[i])
		{
			q.push(i);
			vist[i] = true;
		}
	}
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
#include <queue>
#define N 100020
//std::vector <int> road[N];
//std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int H[N];
int n,m,k,ans,cnt;
struct Node
{
	int v,next;
	long long len;
}edge[4*N];
void addedge(int x,int y,long long val)
{
	cnt++;
	edge[cnt].v = y;
	edge[cnt].len = val;
	edge[cnt].next = H[x];
	H[x] = cnt;
}
struct cmp
{
	bool operator() (const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	//memset(road,0,sizeof(road));
	//memset(val,0,sizeof(val));
	memset(H,-1,sizeof(H));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		addedge(x,y,z);
		addedge(y,x,z);
		//road[x].push_back(y);
		//val[x].push_back(z);
		//road[y].push_back(x);
		//val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp>q;
	memset(vist,0,sizeof(vist));
	q.insert(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		for (int i=H[x];edge[i].next!=-1;i=edge[i].next)
		{
			int y = edge[i].v;
			if (dist[y]==-1||dist[x]+edge[i].len<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + edge[i].len;
				else if (dist[x]+edge[i].len<=dist[y])
				{
					dist[y] = dist[x] + edge[i].len;
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
			dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	dist[1] = 0;
	for (int i=1;i<=n;i++)
	{
		if (dist[i]!=-1)
		{
			q.push(i);
			vist[i] = true;
		}
	}
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#define N 100020
using namespace std;
vector<pair <int,long long> > road[N];
long long dist[N];
int n,m,k,ans;
bool vist[N];
bool flag[N];
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	//while (scanf("%d%d%d",&n,&m,&k)!=EOF)
	scanf("%d%d%d",&n,&m,&k);
	{
		for (int i=1;i<=n;i++)
		{
			int x,y;long long z;
			scanf("%d%d%I64d",&x,&y,&z);
			road[x].push_back(make_pair(y,z));
			road[y].push_back(make_pair(x,z));
		}
		memset(dist,-1,sizeof(dist));
		ans = 0;
		for (int i=1;i<=k;i++)
		{
			int x;long long z;
			scanf("%d%I64d",&x,&z);
			if (dist[x]==-1)
			{
				dist[x] = z;
				flag[x] = true;
			}
			else
			{
				ans++;
				if (z<dist[x]) dist[x] = z;
			}
		}
		set <int,cmp> q; vist[1] = true; dist[1] = 0;
		q.insert(1);
		while (!q.empty())
		{
			int x = *q.begin();q.erase(x);
			for (int i=0;i<road[x].size();i++)
			{
				int y = road[x][i].first;
				long long val = road[x][i].second;
				if (dist[y]>=dist[x]+val&&flag[y])
				{
					flag[y] = false;
					ans++;
				}
				if (dist[y]==-1||dist[y]>dist[x]+val)
				{
					dist[y] = dist[x] + val;
					if (!vist[y])
					{
						vist[y] = true;
						q.insert(y);
					}
				}
			}
			vist[x] = false;
		}
		printf("%d\n",ans);
	}
	return 0;
}


#include <cstdio>
#include <cstring>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#define N 100020
using namespace std;
vector<pair<int,long long>> road[N];
long long dist[N];
int n,m,k,ans;
bool vist[N];
bool flag[N];
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	//while (scanf("%d%d%d",&n,&m,&k)!=EOF)
	scanf("%d%d%d",&n,&m,&k);
	{
		for (int i=1;i<=n;i++)
		{
			int x,y;long long z;
			scanf("%d%d%I64d",&x,&y,&z);
			road[x].push_back(make_pair(y,z));
			road[y].push_back(make_pair(x,z));
		}
		memset(dist,-1,sizeof(dist));
		ans = 0;
		for (int i=1;i<=k;i++)
		{
			int x;long long z;
			scanf("%d%I64d",&x,&z);
			if (dist[x]==-1)
			{
				dist[x] = z;
				flag[x] = true;
			}
			else
			{
				ans++;
				if (z<dist[x]) dist[x] = z;
			}
		}
		set <int,cmp> q; vist[1] = true; dist[1] = 0;
		q.insert(1);
		while (!q.empty())
		{
			int x = *q.begin();q.erase(x);
			for (int i=0;i<road[x].size();i++)
			{
				int y = road[x][i].first;
				long long val = road[x][i].second;
				if (dist[y]>=dist[x]+val&&flag[y])
				{
					flag[y] = false;
					ans++;
				}
				if (dist[y]==-1||dist[y]>dist[x]+val)
				{
					dist[y] = dist[x] + val;
					if (!vist[y])
					{
						vist[y] = true;
						q.insert(y);
					}
				}
			}
			vist[x] = false;
		}
		printf("%d\n",ans);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <int> val[N];
int dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for (int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,0,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		if (dist[x]==0)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
			dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[n] = true;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==0||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==0) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <set>
#include <vector>
#include <iostream>
#include <algorithm>
#define N 100020
using namespace std;
vector<pair <int,long long> > road[N];
long long dist[N];
int n,m,k,ans;
bool vist[N];
bool flag[N];
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	//while (scanf("%d%d%d",&n,&m,&k)!=EOF)
	scanf("%d%d%d",&n,&m,&k);
	{
		for (int i=1;i<=m;i++)
		{
			int x,y;long long z;
			scanf("%d%d%I64d",&x,&y,&z);
			road[x].push_back(make_pair(y,z));
			road[y].push_back(make_pair(x,z));
		}
		memset(dist,-1,sizeof(dist));
		ans = 0;
		for (int i=1;i<=k;i++)
		{
			int x;long long z;
			scanf("%d%I64d",&x,&z);
			if (dist[x]==-1)
			{
				dist[x] = z;
				flag[x] = true;
			}
			else
			{
				ans++;
				if (z<dist[x]) dist[x] = z;
			}
		}
		set <int,cmp> q; vist[1] = true; dist[1] = 0;
		q.insert(1);
		while (!q.empty())
		{
			int x = *q.begin();q.erase(x);
			for (int i=0;i<road[x].size();i++)
			{
				int y = road[x][i].first;
				long long val = road[x][i].second;
				if (dist[y]>=dist[x]+val&&flag[y])
				{
					flag[y] = false;
					ans++;
				}
				if (dist[y]==-1||dist[y]>dist[x]+val)
				{
					dist[y] = dist[x] + val;
					if (!vist[y])
					{
						vist[y] = true;
						q.insert(y);
					}
				}
			}
			vist[x] = false;
		}
		printf("%d\n",ans);
	}
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
#define INF 1<<60
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
//bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	//memset(dist,-1,sizeof(dist));
	for (int i=1;i<=n;i++) dist[i] = INF;
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==INF)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	//memset(vist,0,sizeof(vist));
	dist[1] = 0;
	//for (int i=1;i<=n;i++)
	//{
	//	if (dist[i]!=-1)
	//	{
	//		q.push(i);
	//		vist[i] = true;
	//	}
	//}
	for (int i=1;i<=n;i++) q.insert(i);
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		//q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[x]+val[x][i]<=dist[y])
			{
				q.erase(y);
				dist[y] = dist[x] + val[x][i];
				q.insert(y);
				if (flag[y])
				{
					flag[y] = false;
					ans ++;
				}
				//if (!vist[y])
				//{
				//	vist[y] = true;
				//	q.push(y);
				//}
			}
		}
		//vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <set>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator() (const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp>q;
	memset(vist,0,sizeof(vist));
	q.insert(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = *q.begin();
		q.erase(x);
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <int> val[N];
int dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for (int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,0,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		if (dist[x]==0)
		{
			dist[x] = y;
			flag[x] = true;
		}else if (y<dist[x])
		{
			ans++;
			dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[n] = true;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==0||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==0) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		//road[y].push_back(x);
		//val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	std::queue<int> q;
	memset(vist,0,sizeof(vist));
	q.push(1); vist[1] = true; dist[1] = 0;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					q.push(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]&&a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	memset(vist,0,sizeof(vist));
	dist[1] = 0;
	for (int i=1;i<=n;i++)
	{
		if (dist[i]!=-1)
		{
			//q.push(i);
			q.insert(i);
			vist[i] = true;
		}
	}
	while (!q.empty())
	{
		//int x = q.front();
		int x = *q.begin();
		//q.pop();
		q.erase(x);
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					//q.push(y);
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <set>
#define N 100020
std::vector <int> road[N];
std::vector <long long> val[N];
long long dist[N];
bool flag[N];
bool vist[N];
int n,m,k,ans;
struct cmp
{
	bool operator ()(const int &a,const int &b) const
	{
		return dist[a]<dist[b]||(dist[a]==dist[b]||a<b);
	}
};
int main()
{
	scanf("%d%d%d",&n,&m,&k);
	memset(road,0,sizeof(road));
	memset(val,0,sizeof(val));
	for (int i=1;i<=m;i++)
	{
		int x,y;
		long long z;
		scanf("%d%d%I64d",&x,&y,&z);
		road[x].push_back(y);
		val[x].push_back(z);
		road[y].push_back(x);
		val[y].push_back(z);
	}
	memset(dist,-1,sizeof(dist));
	ans = 0;
	memset(flag,0,sizeof(flag));
	for (int i=1;i<=k;i++)
	{
		int x;
		long long y;
		scanf("%d%I64d",&x,&y);
		if (dist[x]==-1)
		{
			dist[x] = y;
			flag[x] = true;
		}else
		{
			ans ++;
			if (y<dist[x])
				dist[x] = y;
		}
	}
	//std::queue<int> q;
	std::set<int,cmp> q;
	memset(vist,0,sizeof(vist));
	dist[1] = 0;
	for (int i=1;i<=n;i++)
	{
		if (dist[i]!=-1)
		{
			//q.push(i);
			q.insert(i);
			vist[i] = true;
		}
	}
	while (!q.empty())
	{
		//int x = q.front();
		int x = *q.begin();
		//q.pop();
		q.erase(x);
		for (int i=0;i<road[x].size();i++)
		{
			int y = road[x][i];
			if (dist[y]==-1||dist[x]+val[x][i]<=dist[y])
			{
				if (dist[y]==-1) dist[y] = dist[x] + val[x][i];
				else if (dist[x]+val[x][i]<=dist[y])
				{
					dist[y] = dist[x] + val[x][i];
					if (flag[y])
					{
						flag[y] = false;
						ans ++;
					}
				}
				if (!vist[y])
				{
					vist[y] = true;
					//q.push(y);
					q.insert(y);
				}
			}
		}
		vist[x] = false;
	}
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil;
long long a,b,c,jarak[100005];
bool train[100005];
pair<long long, long long> sekarang,nanti;
vector <pair<long long, long long> > kota[300005];
priority_queue <pair<long long, long long> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e17;
	for (int i = 0; i < m; i++)
	{
		scanf("%I64d%I64d%I64d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%I64d%I64d", &a, &b);
		jarak[a] = min(jarak[a], b);
		train[a] = true;
	}
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e17;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e16;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	jarak[1] = 0;
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		dijkstra.push(mp(-jarak[i], i));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= jarak[sekarang.se] + (long long) nanti.fi && train[nanti.se])
				train[nanti.se] = false;
			if (jarak[nanti.se] > jarak[sekarang.se] + (long long) nanti.fi)
			{
				jarak[nanti.se] = jarak[sekarang.se] + (long long) nanti.fi;
				dijkstra.push(mp(-jarak[nanti.se], nanti.se));
			}
		}
	}
	hasil = k;
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e17;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			dijkstra.push(mp(-jarak[i], i));
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 1, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
		train[a] = train[b] = false;
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		if (train[a])
			dijkstra.push(mp(-jarak[a], a));
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] > sekarang.fi + (long long) nanti.fi || (jarak[nanti.se] == sekarang.fi + (long long) nanti.fi && train[nanti.se]))
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		if (train[a])
			dijkstra.push(mp(-jarak[a], a));
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= jarak[sekarang.se] + (long long) nanti.fi && train[nanti.se])
				train[nanti.se] = false;
			if (jarak[nanti.se] > jarak[sekarang.se] + (long long) nanti.fi)
			{
				jarak[nanti.se] = jarak[sekarang.se] + (long long) nanti.fi;
				dijkstra.push(mp(-jarak[nanti.se], nanti.se));
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		if (train[a])
			dijkstra.push(mp(-jarak[a], a));
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] > sekarang.fi + (long long) nanti.fi || (jarak[nanti.se] == sekarang.fi + (long long) nanti.fi && train[nanti.se]))
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[100005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e15;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	for (int i = 1; i <= n; i++)
		if (train[a])
			dijkstra.push(mp(-jarak[a], a));
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		if (jarak[sekarang.se] < sekarang.fi)
			continue;
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil,a,b,c;
long long jarak[100005];
bool train[100005];
pair<long long, int> sekarang,nanti;
vector <pair<int, int> > kota[300005];
priority_queue <pair<long long, int> > dijkstra;

int main()
{
	memset(train, 0, sizeof train);
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e17;
	for (int i = 0; i < m; i++)
	{
		scanf("%d%d%d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%d%d", &a, &b);
		jarak[a] = min(jarak[a], (long long)b);
		train[a] = true;
	}
	hasil = k;
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] >= sekarang.fi + (long long) nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + (long long) nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + (long long) nanti.fi), nanti.se));
				train[nanti.se] = false;
			}
		}
	}
	for (int i = 1; i <= n; i++)
		if (train[i])
			hasil--;
	printf("%d\n", hasil);
	return 0;
}


#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define mp make_pair
using namespace std;

int n,m,k,hasil = 0;
long long a,b,c,jarak[100005];
pair<long long, long long> sekarang,nanti;
vector <pair<long long, long long> > kota[300005];
priority_queue <pair<long long, long long> > dijkstra;

int main()
{
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 2; i <= n; i++)
		jarak[i] = 1e17;
	for (int i = 0; i < m; i++)
	{
		scanf("%I64d%I64d%I64d", &a, &b, &c);
		kota[a].pb(mp(c, b));
		kota[b].pb(mp(c, a));
	}
	jarak[1] = 0;
	dijkstra.push(mp(0, 1));
	while (!dijkstra.empty())
	{
		sekarang = dijkstra.top();
		sekarang.fi = -sekarang.fi;
		dijkstra.pop();
		for (int i = 0; i < kota[sekarang.se].size(); i++)
		{
			nanti = kota[sekarang.se][i];
			if (jarak[nanti.se] > sekarang.fi + nanti.fi)
			{
				jarak[nanti.se] = sekarang.fi + nanti.fi;
				dijkstra.push(mp(-(sekarang.fi + nanti.fi), nanti.se));
			}
		}
	}
	for (int i = 0; i < k; i++)
	{
		scanf("%I64d%I64d", &a, &b);
		if (jarak[a] <= b)
			hasil++;
	}
	printf("%d\n", hasil);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 60;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {}
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  while(q.size())  q.pop();
  q.push(make_pair(0, 1));
  while(!q.empty()) {
    pii p = q.top();
    q.pop();
    ll u = p.second;
    if(vis[u])  continue;
    vis[u] = 1;
    for(int i=0; i<e[u].size(); i++) {
        Edge x = e[u][i];
        if(dis[x.v] > dis[u] + x.len) {
            cnt[x.v] = cnt[u];
            //if(cnt[x.v] > 1e8) cnt[x.v] = 1e8;
            dis[x.v] = dis[u] + x.len;
            q.push(make_pair(dis[x.v], x.v));
        }
        else if(dis[x.v] == dis[u] + x.len) {
            cnt[x.v] += cnt[u];
            if(cnt[x.v > 1e8]) cnt[x.v] = 1e8;
        }
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] =  0;
    cnt[i] = 0;
    e[i].clear();
  }
  a.clear();
  for(int i=1; i<=m; i++) {
    ll u, v, len;
    cin >> u >> v >> len;
    e[u].push_back(Edge{v,len});
    e[v].push_back(Edge{u, len});
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, len;
    cin >> v >> len;
    e[u].push_back(Edge{v, len});
    e[v].push_back(Edge{u, len});
    a.push_back(Edge{v, len});
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
     ll x = a[i].v;
     ll y = a[i].len;
     if(y > dis[x])  ans++;
     else if(y == dis[x] && cnt[x] > 1) {
        ans++;
        cnt[x]--;
     }
  }
  printf("%d\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 30;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {
    }
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    pii p = q.top();
    q.pop();
    ll u = p.second;
    if(vis[u])  continue;
    vis[u] = 1;
    for(int i=0; i<e[u].size(); i++) {
        Edge x = e[u][i];
        if(dis[x.v] > dis[u] + x.len) {
            cnt[x.v] = cnt[u];
            if(cnt[x.v] > 1e6) cnt[x.v] = 1e5;
            dis[x.v] = dis[u] + x.len;
            q.push(make_pair(dis[x.v], x.v));
        }
        else if(dis[x.v] == dis[u] + x.len)
            cnt[x.v] += cnt[u];
            if(cnt[x.v > 1e6]) cnt[x.v] = 1e5;
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] =  0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, len;
    cin >> u >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, len;
    cin >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
    a.push_back(Edge(v, len));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
     ll x = a[i].v;
     ll y = a[i].len;
     if(y > dis[x])  ans++;
     else if(y == dis[x] && cnt[x] > 1) {
        ans++;
        cnt[x]--;
     }
  }
  printf("%d\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 60;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {}
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  while(q.size())  q.pop();
  q.push(make_pair(0, 1));
  while(!q.empty()) {
    pii p = q.top();
    q.pop();
    ll u = p.second;
    if(vis[u])  continue;
    vis[u] = 1;
    for(int i=0; i<e[u].size(); i++) {
        Edge x = e[u][i];
        if(dis[x.v] > dis[u] + x.len) {
            cnt[x.v] = cnt[u];
            //if(cnt[x.v] > 1e8) cnt[x.v] = 1e8;
            dis[x.v] = dis[u] + x.len;
            q.push(make_pair(dis[x.v], x.v));
        }
        else if(dis[x.v] == dis[u] + x.len) {
            cnt[x.v] += cnt[u];
            if(cnt[x.v > 1e8]) cnt[x.v] = 1e8;
        }
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] =  0;
    cnt[i] = 0;
    e[i].clear();
  }
  a.clear();
  for(int i=1; i<=m; i++) {
    ll u, v, len;
    cin >> u >> v >> len;
    e[u].push_back(Edge{v,len});
    e[v].push_back(Edge{u, len});
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, len;
    cin >> v >> len;
    e[u].push_back(Edge{v, len});
    e[v].push_back(Edge{u, len});
    a.push_back(Edge(v, len));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
     ll x = a[i].v;
     ll y = a[i].len;
     if(y > dis[x])  ans++;
     else if(y == dis[x] && cnt[x] > 1) {
        ans++;
        cnt[x]--;
     }
  }
  printf("%d\n", ans);
  return 0;
}


#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pll;
const ll inf = 1ll << 60;
struct Edge {
  ll v, w;
  Edge (ll v, ll w) :
    v(v), w(w) {}
};
priority_queue <pll, vector<pll>, greater<pll> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
bool vis[100010];
int n, m, k;
void dijkstra() {
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    ll x = q.top().second;
    q.pop();
    if(vis[x])  continue;
    vis[x] = 1;
    for(int i=0; i<e[x].size(); i++) {
      Edge t = e[x][i];
      ll v = t.v;
      ll w = t.w;
      if(dis[v] > dis[x] + w) {
         dis[v] = dis[x] + w;
         cnt[v] = cnt[x];
         q.push(make_pair(dis[v], v));
      }
      else if(dis[v] == dis[x] + w) {
         cnt[v] += cnt[x];
         if(cnt[x] > 1e8) cnt[x] = 1e8;
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n,&m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] = 0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, w;
    cin >> u >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, w;
    cin >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
    a.push_back(Edge(v, w));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
    ll x = a[i].v;
    ll y = a[i].w;
    if(y > dis[x]) ans++;
    else if(y == dis[x] && cnt[x] >  1) {
        cnt[x] --;
        ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}


#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pll;
const ll inf = 1ll << 60;
struct Edge {
  ll v, w;
  Edge (ll v, ll w) :
    v(v), w(w) {}
};
priority_queue <pll, vector<pll>, greater<pll> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
bool vis[100010];
int n, m, k;
void dijkstra() {
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    ll x = q.top().second;
    q.pop();
    if(vis[x])  continue;
    vis[x] = 1;
    for(int i=0; i<e[x].size(); i++) {
      Edge t = e[x][i];
      ll v = t.v;
      ll w = t.w;
      if(dis[v] > dis[x] + w) {
         dis[v] = dis[x] + w;
         cnt[v] = cnt[x];
         q.push(make_pair(dis[v], v));
      }
      else if(dis[v] == dis[x] + w) {
         cnt[v] += cnt[x];
         if(cnt[x] > 1e6) cnt[x] = 1e6;
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n,&m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] = 0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, w;
    cin >> u >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, w;
    cin >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
    a.push_back(Edge(v, w));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
    ll x = a[i].v;
    ll y = a[i].w;
    if(y > dis[x]) ans++;
    else if(y == dis[x] && cnt[x] >  1) {
        cnt[x] --;
        ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 30;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {
    }
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    pii p = q.top();
    q.pop();
    ll u = p.second;
    if(vis[u])  continue;
    vis[u] = 1;
    for(int i=0; i<e[u].size(); i++) {
        Edge x = e[u][i];
        if(dis[x.v] > dis[u] + x.len) {
            cnt[x.v] = cnt[u];
            if(cnt[x.v] > 1e8) cnt[x.v] = 1e8;
            dis[x.v] = dis[u] + x.len;
            q.push(make_pair(dis[x.v], x.v));
        }
        else if(dis[x.v] == dis[u] + x.len)
            cnt[x.v] += cnt[u];
            if(cnt[x.v > 1e8]) cnt[x.v] = 1e8;
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] =  0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, len;
    cin >> u >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, len;
    cin >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
    a.push_back(Edge(v, len));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
     ll x = a[i].v;
     ll y = a[i].len;
     if(y > dis[x])  ans++;
     else if(y == dis[x] && cnt[x] > 1) {
        ans++;
        cnt[x]--;
     }
  }
  printf("%d\n", ans);
  return 0;
}


#include <queue>
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pll;
const ll inf = 1ll << 60;
struct Edge {
  ll v, w;
  Edge (ll v, ll w) :
    v(v), w(w) {}
};
priority_queue <pll, vector<pll>, greater<pll> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
bool vis[100010];
int n, m, k;
void dijkstra() {
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    ll x = q.top().second;
    q.pop();
    if(vis[x])  continue;
    vis[x] = 1;
    for(int i=0; i<e[x].size(); i++) {
      Edge t = e[x][i];
      ll v = t.v;
      ll w = t.w;
      if(dis[v] > dis[x] + w) {
         dis[v] = dis[x] + w;
         cnt[v] = cnt[x];
         q.push(make_pair(dis[v], v));
      }
      else if(dis[v] == dis[x] + w) {
         cnt[v] += cnt[x];
        // if(cnt[x] > 1e6) cnt[x] = 1e6;
      }
    }
  }
}
int main() {
  scanf("%d%d%d", &n,&m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] = 0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, w;
    cin >> u >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, w;
    cin >> v >> w;
    e[u].push_back(Edge(v, w));
    e[v].push_back(Edge(u, w));
    a.push_back(Edge(v, w));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
    ll x = a[i].v;
    ll y = a[i].w;
    if(y > dis[x]) ans++;
    else if(y == dis[x] && cnt[x] >  1) {
        cnt[x] --;
        ans++;
    }
  }
  printf("%d\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 30;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {
    }
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  q.push(make_pair(0, 1));
  while(q.size()) {
    pii p = q.top();
    q.pop();
    ll u = p.second;
    if(vis[u])  continue;
    vis[u] = 1;
    for(int i=0; i<e[u].size(); i++) {
        Edge x = e[u][i];
        if(dis[x.v] > dis[u] + x.len) {
            cnt[x.v] = cnt[u];
            //if(cnt[x.v] > 1e8) cnt[x.v] = 1e8;
            dis[x.v] = dis[u] + x.len;
            q.push(make_pair(dis[x.v], x.v));
        }
        else if(dis[x.v] == dis[u] + x.len)
            cnt[x.v] += cnt[u];
            if(cnt[x.v > 1e8]) cnt[x.v] = 1e8;
    }
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
    dis[i] = inf;
    vis[i] =  0;
    cnt[i] = 0;
  }
  for(int i=1; i<=m; i++) {
    ll u, v, len;
    cin >> u >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
  }
  for(int i=1; i<=k; i++) {
    ll u = 1, v, len;
    cin >> v >> len;
    e[u].push_back(Edge(v, len));
    e[v].push_back(Edge(u, len));
    a.push_back(Edge(v, len));
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
     ll x = a[i].v;
     ll y = a[i].len;
     if(y > dis[x])  ans++;
     else if(y == dis[x] && cnt[x] > 1) {
        ans++;
        cnt[x]--;
     }
  }
  printf("%d\n", ans);
  return 0;
}


#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

typedef __int64 ll;
typedef pair<ll, ll> pii;
const ll inf = 1LL << 60;

struct Edge {
  ll v, len;
  Edge (ll v, ll len) :
    v(v), len(len) {}
};
priority_queue <pii, vector<pii>, greater<pii> > q;
vector <Edge> e[100010];
vector <Edge> a;
ll dis[100010], cnt[100010];
int n, m, k;
bool vis[100010];
void dijkstra() {
  //vis[1] = 1;
  dis[1] = 0;
  cnt[1] = 1;
  while(q.size())  q.pop();
  q.push(make_pair(0, 1));
  while(!q.empty()) {
  	pii p = q.top();
  	q.pop();
  	ll val = p.first;
  	ll u = p.second;
  	if(vis[u])  continue;
  	vis[u] = 1;
  	for(int i=0; i<e[u].size(); i++) {
  		Edge x = e[u][i];
  		if(dis[x.v] > val + x.len) {
  			cnt[x.v] = cnt[u];
  			//if(cnt[x.v] > 1e8) cnt[x.v] = 1e8;
  			dis[x.v] = val + x.len;
  			q.push(make_pair(dis[x.v], x.v));
  		}
  		else if(dis[x.v] == val + x.len) {
  			cnt[x.v] += cnt[u];
  			if(cnt[x.v > 1e8]) cnt[x.v] = 1e8;
  		}
  	}
  }
}
int main() {
  scanf("%d%d%d", &n, &m, &k);
  for(int i=1; i<=n; i++) {
  	dis[i] = inf;
  	vis[i] =  0;
  	cnt[i] = 0;
  	e[i].clear();
  }
  a.clear();
  for(int i=1; i<=m; i++) {
  	ll u, v, len;
  	cin >> u >> v >> len;
    e[u].push_back(Edge{v,len});
    e[v].push_back(Edge{u, len});
  }
  for(int i=1; i<=k; i++) {
  	ll u = 1, v, len;
  	cin >> v >> len;
  	e[u].push_back(Edge{v, len});
    e[v].push_back(Edge{u, len});
    a.push_back(Edge{v, len});
  }
  dijkstra();
  int ans = 0;
  for(int i=0; i<a.size(); i++) {
  	 ll x = a[i].v;
  	 ll y = a[i].len;
  	 if(y > dis[x])  ans++;
  	 else if(y == dis[x] && cnt[x] > 1) {
  	 	ans++;
  	 	cnt[x]--;
  	 }
  }
  printf("%d\n", ans);
  return 0;
}