The trafic on the Internet is increasing these days due to smartphones. The wireless carriers have to enhance their network infrastructure.

The network of a wireless carrier consists of a number of base stations and lines. Each line connects two base stations bi-directionally. The bandwidth of a line increases every year and is given by a polynomial f(x) of the year x.

Your task is, given the network structure, to write a program to calculate the maximal bandwidth between the 1-st and N-th base stations as a polynomial of x.



Input

The input consists of multiple datasets. Each dataset has the following format:

N M
u1 v1 p1
...
uM vM pM


The first line of each dataset contains two integers N (2 ≤ N ≤ 50) and M (0 ≤ M ≤ 500), which indicates the number of base stations and lines respectively. The following M lines describe the network structure. The i-th of them corresponds to the i-th network line and contains two integers ui and vi and a polynomial pi. ui and vi indicate the indices of base stations (1 ≤ ui, vi ≤ N); pi indicates the network bandwidth.

Each polynomial has the form of:

aLxL + aL-1xL-1 + ... + a2x2 + a1x + a0

where L (0 ≤ L ≤ 50) is the degree and ai's (0 ≤ i ≤ L, 0 ≤ ai ≤ 100) are the coefficients. In the input,

* each term aixi (for i ≥ 2) is represented as <ai>x^<i>
* the linear term (a1x) is represented as <a1>x;
* the constant (a0) is represented just by digits;
* these terms are given in the strictly decreasing order of the degrees and connected by a plus sign ("+");
* just like the standard notations, the <ai> is omitted if ai = 1 for non-constant terms;
* similarly, the entire term is omitted if ai = 0 for any terms; and
* the polynomial representations contain no space or characters other than digits, "x", "^", and "+".



For example, 2x2 + 3x + 5 is represented as 2x^2+3x+5; 2x3 + x is represented as 2x^3+x, not 2x^3+0x^2+1x+0 or the like. No polynomial is a constant zero, i.e. the one with all the coefficients being zero.

The end of input is indicated by a line with two zeros. This line is not part of any dataset.

Output

For each dataset, print the maximal bandwidth as a polynomial of x. The polynomial should be represented in the same way as the input format except that a constant zero is possible and should be represented by "0" (without quotes).

Example

Input

3 3
1 2 x+2
2 3 2x+1
3 1 x+1
2 0
3 2
1 2 x
2 3 2
4 3
1 2 x^3+2x^2+3x+4
2 3 x^2+2x+3
3 4 x+2
0 0


Output

2x+3
0
2
x+2
#include <iostream>
#include <fstream>
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <iomanip>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

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

#define EPS 1e-9
#define INF MOD
#define MOD 1000000007LL
#define fir first
#define foreach(it,X) for(it=X.begin();it!=X.end();it++)
#define iss istringstream
#define ite iterator
#define ll long long
#define mp make_pair
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<n;i++)
#define pi pair<int,int>
#define pb push_back
#define sec second
#define sst stringstream
#define sz size()
#define vc vector
typedef vc<int> vi;
typedef vc<ll> vl;
typedef vc<string> vs;

struct edge{int to,cap,rev,type;};

vector<edge> g[55];
bool used[55];

void addEdge(int from,int to,int cap){
	edge e;
	e.to=to;e.cap=cap;e.rev=g[to].size();e.type=1;
	g[from].push_back(e);
	e.to=from;e.cap=0;e.rev=g[from].size()-1;e.type=0;
	g[to].push_back(e);
}

int dfs(int v,int t,int f){
	if(v==t)return f;
	used[v]=1;
	rep(i,g[v].size()){
		edge &e=g[v][i];
		if(!used[e.to]&&e.cap>0){
			int d=dfs(e.to,t,min(f,e.cap));
			if(d>0){
				e.cap-=d;
				g[e.to][e.rev].cap+=d;
				return d;
			}
		}
	}
	return 0;
}

int maxFlow(int s,int t){
	int flow=0;
	for(;;){
		fill(used,used+55,0);
		int f=dfs(s,t,INF);
		if(!f)return flow;
		flow+=f;
	}
}

int N,M;
int from[510],to[510],a[510][55];

int main(){
	while(cin>>N>>M && N){
		rep(i,M)rep(j,51)a[i][j]=0;
		rep(i,M){
			int u,v;
			string p;
			cin>>from[i]>>to[i]>>p;
			from[i]--,to[i]--;
			rep(j,p.sz){
				if(p[j]=='+')p[j]=' ';
			}
			iss is(p);
			string s;
			while(is>>s){
				int A=0,B=0;
				int x=0;
				while(x<s.sz && isdigit(s[x])){
					A=A*10+s[x]-'0';
					x++;
				}
				if(x==0)A=1;
				if(x==s.sz){
					a[i][0]=A;
					continue;
				}
				assert(s[x]=='x');
				x++;
				if(x==s.sz){
					a[i][1]=A;
					continue;
				}
				assert(s[x]=='^');
				x++;
				while(x<s.sz && isdigit(s[x])){
					B=B*10+s[x]-'0';
					x++;
				}
				a[i][B]=A;
			}
		}
		
		vi ans(51);
		int higherDeg[55][510]={};
		for(int i=50;i>=0;i--){
			rep(j,N)g[j].clear();
			rep(j,M){
				if(higherDeg[from[j]][g[from[j]].sz]){
					addEdge(from[j],to[j],INF);
				}else{
					addEdge(from[j],to[j],a[j][i]);
				}
				if(higherDeg[to[j]][g[to[j]].sz]){
					addEdge(to[j],from[j],INF);
				}else{
					addEdge(to[j],from[j],a[j][i]);
				}
			}
			ans[i]=maxFlow(0,N-1);
			rep(j,N)rep(k,g[j].sz){
				if(g[j][k].type==1 && g[j][k].cap>0){
					higherDeg[j][k]=1;
				}
			}
		}
		sst ss;
		for(int i=50;i>=0;i--)if(ans[i]>0){
			if(i>1){
				if(ans[i]>1)ss<<ans[i]<<"x^"<<i<<"+";
				else ss<<"x^"<<i<<"+";
			}
			else if(i==1){
				if(ans[i]>1)ss<<ans[i]<<"x+";
				else ss<<"x+";
			}
			else ss<<ans[i]<<"+";
		}
		string out=ss.str();
		if(out!="")cout<<out.substr(0,out.sz-1)<<endl;
		else cout<<0<<endl;
	}
}