#include <bits/stdc++.h>
const int N = 1010;
const long long INF = 1ll << 60;
const int inf = 0x3f3f3f3f;
const long long mod = 998244353;
class Graph {
 public:
  void Init(int n) {
    e_.clear();
    e_.push_back(Edge(0, 0, 1, 0));
    m_ = 0;
    n_ = n;
    hd_.assign(n + 1, 0);
    vis_.assign(n + 1, false);
    connected_num_ = 0;
    for (int i = 1; i <= n; ++i) {
      deg_in_[i] = 0;
    }
  }
  void Init(int n, long long w[]) {
    e_.clear();
    e_.push_back(Edge(0, 0, 1, 0));
    m_ = 0;
    n_ = n;
    hd_.assign(n + 1, 0);
    vis_.assign(n + 1, false);
    connected_num_ = 0;
    for (int i = 1; i <= n; ++i) {
      deg_in_[i] = 0;
      weight[i] = w[i];
    }
  }
  void Add(int u, int v, long long w = 1ll, int type = 0) {
    Edge edge(v, hd_[u], w, type);
    e_.push_back(edge);
    hd_[u] = ++m_;
    ++deg_in_[v];
  }
  int Head(int id_v) { return hd_[id_v]; }
  int Next(int id_e) { return e_[id_e].nxt; }
  int To(int id_e) { return e_[id_e].v; }
  long long& W(int id_e) { return e_[id_e].w; }
  int& Type(int id_e) { return e_[id_e].type; }
  int NumNode() { return n_; }
  long long WNode(int u) { return weight[u]; }

 private:
  struct Edge {
    int v, nxt;
    long long w;
    int type;
    Edge(int _v, int _nxt, long long _w, int _type)
        : v(_v), nxt(_nxt), w(_w), type(_type) {}
  };
  int n_;
  std::vector<int> hd_;
  long long weight[N];
  int m_;
  std::vector<Edge> e_;
  std::vector<bool> vis_;
  int deg_in_[N];
  int connected_num_;
} graph;
class Dijkstra {
 public:
  Dijkstra() {}
  void Init(int n) {
    for (int i = 1; i <= n; ++i) {
      dis_[i] = -1;
      vis_[i] = false;
      num_[i] = 0;
    }
    while (!q_.empty()) {
      q_.pop();
    }
  }
  void InitState(int sta, long long dis) {
    q_.push((HeapNode){sta, dis});
    dis_[sta] = dis;
    num_[sta] = 1ll;
  }
  void Solve(Graph& graph) {
    while (!q_.empty()) {
      HeapNode x = q_.top();
      q_.pop();
      int& sta = x.sta;
      long long& dis = x.dis;
      if (vis_[sta]) {
        continue;
      }
      assert(dis == dis_[sta]);
      vis_[sta] = true;
      for (int i = graph.Head(sta); i; i = graph.Next(i)) {
        int sta_nxt = graph.To(i);
        long long w = graph.W(i);
        if (dis_[sta_nxt] == -1ll || dis_[sta_nxt] > dis_[sta] + w) {
          dis_[sta_nxt] = dis_[sta] + w;
          num_[sta_nxt] = num_[sta];
          q_.push((HeapNode){sta_nxt, dis_[sta_nxt]});
        } else if (dis_[sta_nxt] == dis_[sta] + w) {
          num_[sta_nxt] = (num_[sta_nxt] + num_[sta]) % mod;
        }
      }
    }
  }
  long long ShortestDis(int sta) { return dis_[sta]; }
  long long ShortestNum(int sta) { return num_[sta]; }

 private:
  struct HeapNode {
    int sta;
    long long dis;
    bool operator<(const HeapNode& rhs) const { return dis > rhs.dis; }
  };
  std::priority_queue<HeapNode> q_;
  long long dis_[N];
  bool vis_[N];
  long long num_[N];
} dij[N];
int n, m, k;
int x[N], y[N], z[N];
int a[N], b[N];
long long ans;
int main() {
  scanf("%d%d%d", &n, &m, &k);
  graph.Init(n);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d%d", &x[i], &y[i], &z[i]);
    graph.Add(x[i], y[i], z[i]);
    graph.Add(y[i], x[i], z[i]);
  }
  for (int i = 1; i <= k; ++i) {
    scanf("%d%d", &a[i], &b[i]);
  }
  for (int i = 1; i <= n; ++i) {
    dij[i].Init(n);
    dij[i].InitState(i, 0);
    dij[i].Solve(graph);
  }
  for (int i = 1; i <= m; ++i) {
    long long sum = 0;
    for (int j = 1; j <= k; ++j) {
      long long mi = dij[a[j]].ShortestDis(b[j]);
      mi = std::min(mi,
                    dij[a[j]].ShortestDis(x[i]) + dij[b[j]].ShortestDis(y[i]));
      mi = std::min(mi,
                    dij[a[j]].ShortestDis(y[i]) + dij[b[j]].ShortestDis(x[i]));
      sum += mi;
    }
    ans = (i == 1 ? sum : std::min(ans, sum));
  }
  printf("%lld\n", ans);
  return 0;
}
