// Original C++ solution (slower):
// I'm the Topcoder

//C

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <ctype.h>

#include <math.h>

#include <time.h>

//C++

#include <iostream>

#include <algorithm>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <cstring>

#include <cctype>

#include <stack>

#include <string>

#include <list>

#include <queue>

#include <map>

#include <vector>

#include <deque>

#include <set>

using namespace std;



//*************************OUTPUT*************************

#ifdef WIN32

#define INT64 "%I64d"

#define UINT64 "%I64u"

#else

#define INT64 "%lld"

#define UINT64 "%llu"

#endif



//**************************CONSTANT***********************

#define INF 0x7F7F7F7F

#define eps 1e-8

#define PI acos(-1.)

#define PI2 asin (1.);

typedef long long LL;

//typedef __int64 LL;   //codeforces

typedef unsigned int ui;

typedef unsigned long long ui64;

#define MP make_pair

typedef vector<int> VI;

typedef pair<int, int> PII;

#define pb push_back

#define mp make_pair



//***************************SENTENCE************************

#define CL(a,b) memset (a, b, sizeof (a))

#define sqr(a,b) sqrt ((double)(a)*(a) + (double)(b)*(b))



//****************************FUNCTION************************

template <typename T> double DIS(T va, T vb) { return sqr(va.x - vb.x, va.y - vb.y); }

template <class T> inline T INTEGER_LEN(T v) { int len = 1; while (v /= 10) ++len; return len; }

template <typename T> inline T square(T va, T vb) { return va * va + vb * vb; }



// aply for the memory of the stack

#pragma comment (linker, "/STACK:1024000000,1024000000")

//end



#define CY 105

typedef int typec;



bool inset[CY], vis[CY];

typec wage[CY];

int g[CY][CY];

int N, M;



typec Search(int n, int &s, int &t) {

	memset(vis, false, n * sizeof(vis[0]));

	memset(wage, 0, n * sizeof(wage[0]));

	s = t = -1;

	typec cf, mx;

	int u = 0;

	for (int i = 0; i < n; ++i) {

		mx = -INF;

		for (int j = 0; j < n; ++j) {

			if (!inset[j] && !vis[j] && mx < wage[j]) {

				mx = wage[u = j];

			}

		}

		if (u == t) return cf;

		s = t; t = u;

		cf = mx;

		vis[u] = true;

		for (int v = 0; v < n; ++v) {

			if (!inset[v] && !vis[v]) {

				wage[v] += g[u][v];

			}

		}

	}

	return cf;

}



typec Stoer_Wagner(int n) {

	int s, t;

	typec ans = INF, cf;

	memset(inset, false, n * sizeof(inset[0]));

	for (int i = 1; i < n; ++i) {

		cf = Search(n, s, t);

		ans = min(ans, cf);

		if (ans == 0) return ans;

		inset[t] = true;

		for (int j = 0; j < n; ++j) {

			if (!inset[j] && j != s) {

				g[s][j] += g[t][j];

				g[j][s] += g[j][t];

			}

		}

	}

	return ans;

}



int main(void) {

	while (2 == scanf("%d%d", &N, &M)) {

		if (N == 0 && M == 0) break;

		memset(g, 0, sizeof(g));

		int ans = 0, u, v, c;

		for (int i = 0; i < M; ++i) {

			scanf("%d%d%d", &u, &v, &c);

			if (c > 0) g[u][v] += c, g[v][u] += c;

			else ans += c;

		}

		printf("%d\n", ans + Stoer_Wagner(N));

	}

	return 0;

}

// Optimized solution to the same problem (faster):
#include <stdio.h>

#include <string.h>

#include <algorithm>

using namespace std;





const int inf = 0x3f3f3f3f ;

const int maxw = 1000 ;

int g[105][105] , w[105] ;

int a[105] , v[105] , na[105] ;

int n , m ;

int mincut( int n ) {

	int i , j, pv , zj ;

	int best = inf ;

	for( i = 0 ; i < n; i ++ ) {

		v[i] = i ;

	}

	while( n > 1 ) {

		for( a[v[0]] = 1 , i = 1 ; i < n; i ++ ) {

			a[v[i]] = 0 ; na[i-1] = i ;

			w[i] = g[v[0]][v[i]] ;

		}

		for( pv = v[0] ,i = 1 ; i < n ; i ++ ) {

			for( zj = -1 , j = 1 ; j < n ; j ++ ) 

				if( !a[v[j]] && (zj<0||w[j]>w[zj]))

					zj = j ;

				a[v[zj]] = 1 ;

				if( i == n - 1 ) {

					if( best > w[zj] ) best = w[zj] ;

					for( i = 0 ; i < n;  i++ ) {

						g[v[i]][pv] = g[pv][v[i]] +=g[v[zj]][v[i]] ;

					}

					v[zj] = v[--n] ;

					break;

				}

				pv = v[zj] ;

				for( j = 1 ; j < n; j ++ ) if( !a[v[j]])

					w[j] += g[v[zj]][v[j]] ;

		}

	}

	return best ;

}



int main(){

	while( scanf( "%d%d" , &n , &m ) != EOF ) {

		if( n == 0 && m == 0 ) break;

		memset( g , 0 , sizeof(g) ) ;

		int ans = 0 ;

		int i ;

		for( i = 1 ; i <= m ;i ++ ) {

			int from , to ,val ;

			scanf( "%d%d%d" , &from , &to , &val ) ;

			if( val < 0 ) {

				ans += val ;

				continue ;

			}

			if( g[from][to] == inf ) {

				g[from][to] = val ;

			}else{

				g[from][to] += val ;

			}

			g[to][from] = g[from][to] ;

		}

		printf( "%d\n" , ans + mincut(n) )  ;

	}

	return 0 ;

}

// Fastest known solution for this problem: