Problem: Background

The kindergarten attached to the University of Aizu is a kindergarten where children who love programming gather. Yu, one of the kindergarten children, loves drawing as much as programming. So far, Yu-kun has drawn many pictures with circles and arrows. The arrows are always drawn to connect the circles. One day Yu finds out that these pictures are graphs.

It seems that circles are called vertices and arrows are called edges. Furthermore, when drawing an arrow, Yu always wrote one positive integer on it. A graph consisting of directed edges with weights in this way is called a weighted directed graph.

Today Yu-kun learned a new word, the cycle of the cycle. A cycle is a sequence of connected edges in which all vertices appear at most once, and the first and last vertices are the same. If the sum of the weights of the edges of a cycle is negative, then such a cycle is called a negative cycle.

Yu-kun, who knew a lot of new words, came up with a problem.

Problem

A weighted directed graph with no cycle is given. Select two different vertices i and j and add one directed edge with weight w (w <0) from i to j. Find i and j in the graph that create a negative cycle, and find the maximum sum of the weights of the sides that belong to that negative cycle. If such i, j does not exist, output "NA".

Constraints

The input satisfies the following conditions.

* 2 ≤ V ≤ 100000
* 1 ≤ E ≤ 500000
* -100 ≤ w <0
* 0 ≤ ci ≤ 100 (0 ≤ i ≤ E-1)
* 0 ≤ si, ti ≤ V-1 (0 ≤ i ≤ E-1)
* The same si and ti pair never appears while typing
* si and ti are different

Input


V E w
s0 t0 c0
s1 t1 c1
...
s (E-1) t (E-1) c (E-1)


The number of vertices V, the number of edges E, and the weight w of the edge to be added are given in the first line, separated by blanks.

The information of the directed edge is given as si ti ci in the following E line. (0 ≤ i ≤ E-1)

This means that there is a directed edge of the weight ci from si to ti.

Output

Output the maximum value of the sum of the weights of the sides belonging to the negative cycle, which can be created by adding the directed side of the weight w, to one line. If a negative cycle cannot be created no matter where you add an edge, output "NA".

Examples

Input

3 2 -3
0 1 1
0 2 5


Output

-2


Input

3 2 -1
0 1 1
0 2 5


Output

NA


Input

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


Output

-1


Input

5 4 -30
0 1 1
1 3 15
1 4 4
2 1 3


Output

-12

Solution (in CPP):

Solution:
#include <iostream>
#include <vector>

using namespace std;

class range {
private:
  struct Iterator {
    int val;
    int operator*() {return val;}
    bool operator!=(Iterator &itr) {return val < itr.val;}
    void operator++() {++val;}
  };
  Iterator i, n;
public:
  range(int n) : i({0}), n({n}) {}
  range(int i, int n) : i({i}), n({n}) {}
  Iterator &begin() {return i;}
  Iterator &end() {return n;}
};

template<class T> T at(vector<T> v, int i) {return v[(i % (int)v.size() + v.size()) % v.size()];}

typedef int Weight;
struct Edge {
  int from, to;
  Weight weight;
  Edge(int from, int to, Weight weight) :
    from(from), to(to), weight(weight) {}
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;

Matrix adjacency(const Graph &graph) {
  int n = graph.size();
  Matrix distance(n, Array(n, 1e9));
  for (const Edges &edges : graph) for (const Edge &edge : edges) {
    distance[edge.from][edge.to] = edge.weight;
  }
  return distance;
}

void debug(const Graph &g) {
  for (const Edges &es : g) for (const Edge &e : es) {
    cerr << e.from << " " << e.to << " " << e.weight << endl;
  }
}

#include <algorithm>

bool visit(const Graph &g, int v, vector<int> &order, vector<int> &color) {
  color[v] = 1;
  for (const Edge &e : g[v]) {
    if (color[e.to] == 2) continue;
    if (color[e.to] == 1) return false;
    if (!visit(g, e.to, order, color)) return false;
  }
  order.emplace_back(v);
  color[v] = 2;
  return true;
}

bool topologicalSort(const Graph &g, vector<int> &order) {
  vector<int> color(g.size(), 0);
  order.clear();
  for (int u : range(g.size())) if (!color[u] && !visit(g, u, order, color)) return false;
  reverse(order.begin(), order.end());
  return true;
}

bool dp[100000][100];

int main() {
  int v, e, w;
  cin >> v >> e >> w;
  Graph graph(v), graph_r(v);
  for (int i : range(e)) {
    int s, t, c;
    cin >> s >> t >> c;
    graph[s].emplace_back(s, t, c);
    graph_r[t].emplace_back(t, s, c);
  }
  vector<int> order;
  topologicalSort(graph, order);
  reverse(order.begin(), order.end());
  for (int i : range(v)) dp[i][0] = true;
  int res = -1000;
  for (int i : range(v)) {
    int t = order[i];
    for (const auto &edge : graph_r[t]) {
      for (int j : range(100)) if (dp[t][j]) {
        if (j + edge.weight + w < 0) res = max(res, j + edge.weight + w);
        if (j + edge.weight < 100)  dp[edge.to][j + edge.weight] = true;
      }
    }
  }
  if (res == -1000) cout << "NA" << endl;
  else cout << res << endl;
}