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>
using namespace std;

int number(string s) {
    int ret = 0, pos = 0;
    while (pos < (int)s.size() && isdigit(s[pos])) {
        ret = ret * 10 + (s[pos] - '0');
        pos++;
    }
    return ret;
}

class Capacity {
public:
    int coef[102] = {};
    int dim = 0;

    Capacity(){};
    Capacity(string s) {
        int prev_pos = 0;
        int x_pos = -1, pow_pos = -1;
        for (int i = 0; i <= (int)s.size(); i++) {
            if (i == (int)s.size() || s[i] == '+') {
                auto term = s.substr(prev_pos, i-prev_pos);

                int c = 1;
                if (x_pos != prev_pos) c = number(term);

                int d = 0;
                if (pow_pos != -1) d = number(term.substr(pow_pos-prev_pos+1));
                else if (x_pos != -1) d = 1;

                coef[d] = c;
                dim = max(dim, d);

                x_pos = -1, pow_pos = -1;
                prev_pos = i + 1;
            } else if (s[i] == 'x') {
                x_pos = i;
            } else if (s[i] == '^') {
                pow_pos = i;
            }
        }
    }
    bool is_zero(){
        return (dim == 0 && coef[0] == 0);
    }

    void output() {
        string ret = "";
        for (int i = dim; i >= 0; i--) {
            if (coef[i] == 0 && ret.size() > 0)
                continue;

            if (ret.size() && coef[i] >= 0) ret += "+";
            if (coef[i] > 1 || (i == 0 && coef[i] == 1) || (i == 0 && ret.size() == 0))
                ret += to_string(coef[i]);
            if (i != 0) ret += "x";
            if (i > 1){
                ret += "^";
                ret += to_string(i);
            }
        }
        cout << ret << endl;
    }
};
Capacity operator+(const Capacity &lv, const Capacity &rv) {
    Capacity ret;
    int dim = max(lv.dim, rv.dim);
    for (int i = 0; i <= dim; i++) {
        ret.coef[i] = lv.coef[i] + rv.coef[i];
    }
    ret.dim = dim;
    return ret;
}
Capacity operator-(const Capacity &lv, const Capacity &rv) {
    Capacity ret;

    int dim = max(lv.dim, rv.dim);
    bool erase = true;
    for (int i = dim; i >= 0; i--) {
        ret.coef[i] = lv.coef[i] - rv.coef[i];

        if (erase && ret.coef[i] == 0) dim--;
        else erase = false;
    }
    if (dim < 0) dim = 0;
    ret.dim = dim;
    return ret;
}
bool operator>(const Capacity &lv, const Capacity &rv) {
    if (lv.dim != rv.dim) return lv.dim > rv.dim;
    for (int i = lv.dim; i >= 0; i--) {
        if (lv.coef[i] == rv.coef[i])
            continue;
        return lv.coef[i] > rv.coef[i];
    }
    return false;
}
Capacity min(Capacity &a, Capacity &b) {
    if (a > b) return b;
    return a;
}

struct edge {
    int to;
    Capacity cap;
    int rev;
};

int N, M;
vector<vector<edge>> G;
bool used[51];
Capacity max_cap("101x^101");

void add_edge(int from, int to, const Capacity &cap) {
    G[from].push_back({to, cap, (int)G[to].size()});
    G[to].push_back({from, Capacity(), (int)G[from].size() - 1});
}

Capacity dfs(int v, int t, Capacity f) {
    if (v == N-1) return f;
    used[v] = true;
    for (int i = 0; i < (int)G[v].size(); i++) {
        edge &e = G[v][i];
        if (!used[e.to] && !e.cap.is_zero()) {
            Capacity d = dfs(e.to, t, min(f, e.cap));
            if (!d.is_zero()) {
                e.cap = e.cap - d;
                G[e.to][e.rev].cap = G[e.to][e.rev].cap + d;
                return d;
            }
        }
    }
    return Capacity();
}

int main() {
    while (cin >> N >> M, N + M) {
        G = vector<vector<edge>>(N);
        for (int i = 0; i < M; i++) {
            int from, to; string exp;
            cin >> from >> to >> exp;
            from--, to--;
            add_edge(from, to, Capacity(exp));
            add_edge(to, from, Capacity(exp));
        }

        Capacity flow;
        while (true)
        {
            memset(used, false, sizeof(used));
            Capacity f = dfs(0, N-1, max_cap);
            if (f.is_zero()) break;
            flow = flow + f;
        }
        flow.output();
    }
}

