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 <bits/stdc++.h>
#define INF 1e9
#define MAX_V 100
using namespace std;
typedef vector<int> V;
const V zero(51,0);
struct edge{
  int to,rev;
  V cap;
  edge();
  edge(int to,V cap,int rev):to(to),cap(cap),rev(rev){};
};

bool compare (const V &a,const V &b){
  for(int i=a.size()-1;i>=0;i--)if(a[i]!=b[i])return a[i]<b[i];
  return 0;
}
V min(V a,V b){return compare(a,b)? a:b;}

vector<edge> G[MAX_V]; //??°???????????£??\?????????
bool used[MAX_V];      //DFS??§?????§??????????????????????????°
//from??????to??????????????????cap???????????°?????????????????????
void add_edge(int from,int to,V cap){
  G[from].push_back(edge(to,cap,G[to].size()));
  G[to].push_back(edge(from,zero,G[from].size()-1));  
}

void add(V &a,V b){for(int i=0;i<(int)a.size();i++)a[i]+=b[i];}
void sub(V &a,V b){for(int i=0;i<(int)a.size();i++)a[i]-=b[i];}

//?¢?????????????DFS??§??¢???
V dfs(int v,int t,V f){
  if(v == t)return f;
  used[v]=true;
  for(int i=0; i<G[v].size() ;i++){
    edge &e = G[v][i];
    if(!used[e.to] && e.cap != zero){
      V d = dfs(e.to ,t , min(f,e.cap));
      if(d != zero){
	sub(e.cap,d);
	add(G[e.to][e.rev].cap,d);
	return d;
      }
    }
  }
  return zero;
}

//s??????t???????????§???????±???????
V max_flow(int s,int t){
  V flow=zero;
  for(;;){
    memset(used,0,sizeof(used));
    V f = dfs(s, t, V(51,1e4));
    if(f == zero)return flow;
    add(flow,f);
  }
}


int StoI(string &a,int &i){
  int res=0;
  while(isdigit(a[i])) res=res*10+a[i++]-'0';
  return res;
}

string ItoS(int a){
  string res;
  while(a) res=char(a%10+'0')+res,a/=10;
  if(res.empty()) res="0";
  return res;
}

V StoV(string s){
  V res(51);
  if(s=="0") return zero;
  for(int i=0;i<s.size();i++){
    int a = max(1,StoI(s,i));
    int L = 0;
    if(s[i]=='x')i+=1+(s[i+1]=='^'),L=max(1,StoI(s,i));
    res[L] = a;
  }
  return res;
}

string VtoS(V a){
  string res;
  for(int i=a.size()-1;i>=0;i--){
    if(a[i]==0)continue;
    if(!res.empty()) res+='+';
    if(a[i]>1||i==0) res+=ItoS(a[i]);
    if(i)res+='x';
    if(i>1) res+='^'+ItoS(i);
  }
  if(res.empty()) res="0";
  return res;
}

int main(){
  while(1){
  int n,m;
  cin>>n>>m;
  if(!n&&!m) return 0;
  for(int i=0;i<MAX_V;i++) G[i].clear();
  for(int i=0,a,b;i<m;i++){
    string c;
    cin>>a>>b>>c;
    V vc = StoV(c);
    add_edge(a-1,b-1,vc);
    add_edge(b-1,a-1,vc);
  }

  V ans = max_flow(0,n-1);
  cout<<VtoS(ans)<<endl;
  }
  return 0;
}