Find the sum of the weights of edges of the Minimum-Cost Arborescence with the root r for a given weighted directed graph G = (V, E).

Constraints

* 1 ≤ |V| ≤ 100
* 0 ≤ |E| ≤ 1,000
* 0 ≤ wi ≤ 10,000
* G has arborescence(s) with the root r

Input


|V| |E| r
s0 t0 w0
s1 t1 w1
:
s|E|-1 t|E|-1 w|E|-1


, where |V| is the number of vertices and |E| is the number of edges in the graph. The graph vertices are named with the numbers 0, 1,..., |V|-1 respectively. r is the root of the Minimum-Cost Arborescence.

si and ti represent source and target verticess of i-th directed edge. wi represents the weight of the i-th directed edge.

Output

Print the sum of the weights the Minimum-Cost Arborescence.

Examples

Input

4 6 0
0 1 3
0 2 2
2 0 1
2 3 1
3 0 1
3 1 5


Output

6


Input

6 10 0
0 2 7
0 1 1
0 3 5
1 4 9
2 1 6
1 3 2
3 4 3
4 2 2
2 5 8
3 5 3


Output

11
#include <bits/stdc++.h>
using Int = int64_t;
using UInt = uint64_t;
using C = std::complex<double>;
#define rep(i, n) for(Int i = 0; i < (Int)(n); ++i)
#define guard(x) if( not (x) ) continue;
#ifndef LOCAL_
#define fprintf if( false ) fprintf
#endif

template<typename T>
using RQ = std::priority_queue<T, std::vector<T>, std::greater<T>>;

struct Tree {
   Tree(Int n)
      : ps(n, -1) {}
   std::vector<Int> ps;
   Int root(Int x) {
      if( ps[x] == -1 ) return x;
      return ps[x] = root(ps[x]);
   }
   void connect(Int parent, Int child) {
      parent = root(parent), child = root(child);
      if( parent == child ) return;
      ps[root(child)] = root(parent);
   }
};

int main() {
   Int v, e, r;
   std::cin >> v >> e >> r;
   std::vector<Int> ss(e), ts(e), ws(e);
   rep(i, e) std::cin >> ss[i] >> ts[i] >> ws[i];
   std::vector<RQ<std::pair<Int,Int>>> qs(v);
   std::vector<Int> os(v);
   rep(i, e) {
      Int s = ss[i], t = ts[i], w = ws[i];
      qs[t].emplace(w, s);
   }
   Tree tree(v);
   auto f = [&]() -> Int {
      Int res = 0;
      std::vector<Int> pws(v), pis(v);
      std::vector<bool> finished(v);
      finished[r] = true;
      rep(i, v) {
         Int a = tree.root(i);
         guard( not finished[a] );
         std::vector<Int> ys;
         std::vector<bool> visited(v);
         while( not finished[a] ) {
            ys.emplace_back(a);
            visited[a] = true;
            if( qs[a].empty() ) return -1;
            Int w, p;
            do {
               std::tie(w, p) = qs[a].top(); qs[a].pop();
               w += os[a];
               p = tree.root(p);
            } while( p == tree.root(a) );
            pws[a] = w;
            pis[a] = p;
            res += w;
            if( not visited[p] ) {
               a = p;
            }
            else {
               Int nr = a;
               for(Int b = pis[a]; b != a; b=pis[b]) {
                  if( qs[nr].size() < qs[b].size() ) nr = b;
               }
               os[nr] -= pws[nr];
               for(Int b = pis[nr]; b != nr; b=pis[b]) {
                  tree.connect(nr, b);
                  while( not qs[b].empty() ) {
                     Int w2, p2; std::tie(w2, p2) = qs[b].top(); qs[b].pop();
                     Int nw = w2 + os[b] - pws[b] - os[nr];
                     qs[nr].emplace(nw, p2);
                  }
               }
               a = nr;
            }
         }
         for(Int y : ys) finished[y] = true;
      }
      return res;
   };
   printf("%ld\n", f());
}

