Imagine that there is a group of three friends: A, B and С. A owes B 20 rubles and B owes C 20 rubles. The total sum of the debts is 40 rubles. You can see that the debts are not organized in a very optimal manner. Let's rearrange them like that: assume that A owes C 20 rubles and B doesn't owe anything to anybody. The debts still mean the same but the total sum of the debts now equals 20 rubles.

This task is a generalisation of a described example. Imagine that your group of friends has n people and you know the debts between the people. Optimize the given debts without changing their meaning. In other words, finally for each friend the difference between the total money he should give and the total money he should take must be the same. Print the minimum sum of all debts in the optimal rearrangement of the debts. See the notes to the test samples to better understand the problem.

Input

The first line contains two integers n and m (1 ≤ n ≤ 100; 0 ≤ m ≤ 104). The next m lines contain the debts. The i-th line contains three integers ai, bi, ci (1 ≤ ai, bi ≤ n; ai ≠ bi; 1 ≤ ci ≤ 100), which mean that person ai owes person bi ci rubles.

Assume that the people are numbered by integers from 1 to n.

It is guaranteed that the same pair of people occurs at most once in the input. The input doesn't simultaneously contain pair of people (x, y) and pair of people (y, x).

Output

Print a single integer — the minimum sum of debts in the optimal rearrangement.

Examples

Input

5 3
1 2 10
2 3 1
2 4 1


Output

10


Input

3 0


Output

0


Input

4 3
1 2 1
2 3 1
3 1 1


Output

0

Note

In the first sample, you can assume that person number 1 owes 8 rubles to person number 2, 1 ruble to person number 3 and 1 ruble to person number 4. He doesn't owe anybody else anything. In the end, the total debt equals 10.

In the second sample, there are no debts.

In the third sample, you can annul all the debts.
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Stream;

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		Scanner in = new Main().new Scanner(inputStream);
		Writer out = new Main().new Writer(outputStream);
		Main solver = new Main();
		solver.solve(in, out);
	}

	public void solve(Scanner in, Writer out) {
		int n = in.ni(), m = in.ni();
		int[] flow_in = new int[n];
		int[] flow_out = new int[n];
		long sum = 0;
		for (int i = 0; i < m; i++) {
			int a = in.ni(), b = in.ni(), c = in.ni();
			flow_out[a-1] += c;
			flow_in[b-1] += c;
		}
		long total = 0;
		for (int i = 0; i < n; i++) {
			int fin = flow_in[i];
			int fout = flow_out[i];
			if(fin < fout) {
				total += fout - fin;
			}
		}
		System.out.println(total);
	}
	
	public int[] strToIntArr(String[] arr) {
		return Stream.of(arr).mapToInt(Integer::parseInt).toArray();
	}

	public boolean deq(double a, double b) {
		return Math.abs(a - b) < 0.0001;
	}

	public double dist(double a, double b, double c, double d) {
		return Math.sqrt((a - c) * (a - c) + (b - d) * (b - d));
	}

	public boolean hasMore(String line) {
		return line != null && !line.equals("");
	}

	public int max(int a, int b, int c) {
		return Math.max(a, Math.max(b, c));
	}

	public int min(int a, int b, int c) {
		return Math.min(a, Math.min(b, c));
	}

	class Writer {
		PrintWriter output;

		public Writer(OutputStream out) {
			this.output = new PrintWriter(new OutputStreamWriter(out));
		}

		public void println(Object s) {
			output.println(s.toString());
		}

		public void print(Object s) {
			output.print(s.toString());
		}

		public void flush() {
			output.flush();
		}
	}

	class Scanner {
		BufferedReader br;
		StringTokenizer in;

		public Scanner(InputStream inputStream) {
			br = new BufferedReader(new InputStreamReader(inputStream));
		}

		public String next() {
			return hasMoreTokens() ? in.nextToken() : null;
		}

		public String readLine() {
			try {
				return br.readLine();
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}

		boolean hasMoreTokens() {
			while (in == null || !in.hasMoreTokens()) {
				String s = readLine();
				if (s == null)
					return false;
				in = new StringTokenizer(s);
			}
			return true;
		}

		public String nextString() {
			return next();
		}

		public int ni() {
			return Integer.parseInt(nextString());
		}

		public double nd() {
			return Double.parseDouble(nextString());
		}

		public long nl() {
			return Long.parseLong(nextString());
		}

		public int[] nia(int n) {
			int[] a = new int[n];
			for (int i = 0; i < n; i++) {
				a[i] = ni();
			}
			return a;
		}

		public long[] nla(int n) {
			long[] a = new long[n];
			for (int i = 0; i < n; i++) {
				a[i] = ni();
			}
			return a;
		}
	}

	class Pair implements Comparable<Pair> {
		long _first, _second;

		public Pair(int f, int s) {
			_first = f;
			_second = s;
		}

		public Pair(Long f, Long s) {
			_first = f;
			_second = s;
		}

		public int compareTo(Pair o) {
			if (this.first() != o.first())
				return Long.compare(this.first(), o.first());
			else
				return Long.compare(this.second(), o.second());
		}

		long first() {
			return _first;
		}

		long second() {
			return _second;
		}

		int firsti() {
			return (int) _first;
		}

		int secondi() {
			return (int) _second;
		}
	}

	class Triple implements Comparable<Triple> {
		Integer _first, _second, _third;

		public Triple(Integer f, Integer s, Integer t) {
			_first = f;
			_second = s;
			_third = t;
		}

		public int compareTo(Triple o) {
			if (!this.first().equals(o.first()))
				return this.first() - o.first();
			else if (!this.second().equals(o.second()))
				return this.second() - o.second();
			else
				return this.third() - o.third();
		}

		Integer first() {
			return _first;
		}

		Integer second() {
			return _second;
		}

		Integer third() {
			return _third;
		}

		public String toString() {
			return first() + " " + second() + " " + third();
		}
	}

	class UnionFind {
		private ArrayList<Integer> p, rank, setSize;
		private int numSets;

		public UnionFind(int N) {
			p = new ArrayList<>(N);
			rank = new ArrayList<>(N);
			setSize = new ArrayList<>(N);
			numSets = N;
			for (int i = 0; i < N; i++) {
				p.add(i);
				rank.add(0);
				setSize.add(1);
			}
		}

		public int find(int i) {
			if (p.get(i) == i)
				return i;
			else {
				int ret = find(p.get(i));
				p.set(i, ret);
				return ret;
			}
		}

		public boolean connected(int i, int j) {
			return find(i) == find(j);
		}

		public void union(int i, int j) {
			if (!connected(i, j)) {
				numSets--;
				int x = find(i), y = find(j);
				if (rank.get(x) > rank.get(y)) {
					p.set(y, x);
					setSize.set(x, setSize.get(x) + setSize.get(y));
				} else {
					p.set(x, y);
					setSize.set(y, setSize.get(y) + setSize.get(x));
					if (rank.get(x) == rank.get(y))
						rank.set(y, rank.get(y) + 1);
				}
			}
		}

		public int numDisjointSets() {
			return numSets;
		}

		public int size(int i) {
			return setSize.get(find(i));
		}
	}

	class SegmentTree {
		private int[] st, A;
		private int n;
		private boolean min;

		public SegmentTree(int[] _A, boolean _min) {
			min = _min;
			A = _A;
			n = A.length;
			st = new int[4 * n];
			for (int i = 0; i < 4 * n; i++)
				st[i] = 0;
			build(1, 0, n - 1);
		}

		private int left(int p) {
			return p << 1;
		}

		private int right(int p) {
			return (p << 1) + 1;
		}

		private void build(int p, int L, int R) {
			if (L == R)
				st[p] = A[L]; // L
			else {
				build(left(p), L, (L + R) / 2);
				build(right(p), (L + R) / 2 + 1, R);
				int p1 = st[left(p)], p2 = st[right(p)];
				st[p] = p1 + p2; // ((min && A[p1] <= A[p2]) || (!min && A[p1] >= A[p2])) ? p1 : p2;
			}
		}

		private int rmq(int p, int L, int R, int i, int j) {
			if (i > R || j < L)
				return -1;
			if (L >= i && R <= j)
				return st[p];

			int p1 = rmq(left(p), L, (L + R) / 2, i, j);
			int p2 = rmq(right(p), (L + R) / 2 + 1, R, i, j);

			if (p1 == -1)
				return p2;
			if (p2 == -1)
				return p1;
			return p1 + p2; // ((min && A[p1] <= A[p2]) || (!min && A[p1] >= A[p2])) ? p1 : p2;
		}

		private int update_point(int p, int L, int R, int idx, int new_value) {
			int i = idx, j = idx;

			if (i > R || j < L)
				return st[p];

			if (L == i && R == j) {
				A[i] = new_value;
				return st[p] = A[L];
			}

			int p1, p2;
			p1 = update_point(left(p), L, (L + R) / 2, idx, new_value);
			p2 = update_point(right(p), (L + R) / 2 + 1, R, idx, new_value);
			return st[p] = p1 + p2; // ((min && A[p1] <= A[p2]) || (!min && A[p1] >= A[p2])) ? p1 : p2;
		}

		public int rmq(int i, int j) {
			return rmq(1, 0, n - 1, i, j);
		}

		public int update_point(int idx, int new_value) {
			return update_point(1, 0, n - 1, idx, new_value);
		}
	}

}
