You are given a connected weighted undirected graph without any loops and multiple edges. 

Let us remind you that a graph's spanning tree is defined as an acyclic connected subgraph of the given graph that includes all of the graph's vertexes. The weight of a tree is defined as the sum of weights of the edges that the given tree contains. The minimum spanning tree (MST) of a graph is defined as the graph's spanning tree having the minimum possible weight. For any connected graph obviously exists the minimum spanning tree, but in the general case, a graph's minimum spanning tree is not unique.

Your task is to determine the following for each edge of the given graph: whether it is either included in any MST, or included at least in one MST, or not included in any MST.

Input

The first line contains two integers n and m (2 ≤ n ≤ 105, <image>) — the number of the graph's vertexes and edges, correspondingly. Then follow m lines, each of them contains three integers — the description of the graph's edges as "ai bi wi" (1 ≤ ai, bi ≤ n, 1 ≤ wi ≤ 106, ai ≠ bi), where ai and bi are the numbers of vertexes connected by the i-th edge, wi is the edge's weight. It is guaranteed that the graph is connected and doesn't contain loops or multiple edges.

Output

Print m lines — the answers for all edges. If the i-th edge is included in any MST, print "any"; if the i-th edge is included at least in one MST, print "at least one"; if the i-th edge isn't included in any MST, print "none". Print the answers for the edges in the order in which the edges are specified in the input.

Examples

Input

4 5
1 2 101
1 3 100
2 3 2
2 4 2
3 4 1


Output

none
any
at least one
at least one
any


Input

3 3
1 2 1
2 3 1
1 3 2


Output

any
any
none


Input

3 3
1 2 1
2 3 1
1 3 1


Output

at least one
at least one
at least one

Note

In the second sample the MST is unique for the given graph: it contains two first edges.

In the third sample any two edges form the MST for the given graph. That means that each edge is included at least in one MST.
#include <bits/stdc++.h>
using namespace std;
const long long maxn = 3e5 + 10;
const long double SADAT = 7.84e-17;
const long long INF = 1e9;
const long long mod = 1e9 + 7;
const long double PI = 4 * atan((long double)1);
long long pw(long long a, long long b) {
  return (!b ? 1
             : (b & 1 ? a * pw(a * a % mod, b / 2) % mod
                      : pw(a * a % mod, b / 2) % mod));
}
struct edge {
  int x, y, w, srt;
};
edge edg[maxn];
int n, m, t = 0, df[maxn], crnt, low[maxn], ans[maxn], w[maxn];
int par[maxn], pre[maxn], di[maxn], np[maxn], rg[maxn], out[maxn], cs = 1;
vector<int> comp[maxn];
set<int> st;
bool mark[maxn];
bool cmp(edge i, edge j) { return (i.w < j.w); }
int getpar(int v) {
  if (par[v] == v) {
    return (v);
  }
  par[v] = getpar(par[v]);
  return (par[v]);
}
void merge(int x, int y, int z, int v) {
  out[++cs] = y;
  w[cs] = z, rg[cs] = v;
  np[cs] = di[x];
  di[x] = cs;
}
void dfs(int v) {
  mark[v] = 1;
  df[v] = low[v] = ++t;
  for (int i = di[v]; i != 0 and w[i] == crnt; i = np[i]) {
    if (i != pre[v]) {
      int u = out[i];
      if (mark[u] == 0) {
        pre[u] = i;
        if (pre[u] % 2) {
          pre[u]--;
        } else {
          pre[u]++;
        }
        dfs(u);
        if (low[u] < low[v]) {
          low[v] = low[u];
        }
        if (low[u] > df[v]) {
          ans[rg[i]] = 2;
        }
      }
      if (mark[u] == 1 and low[u] < low[v]) {
        low[v] = low[u];
      }
    }
  }
  if (low[v] == df[v]) {
    t = df[v] - 1;
  }
}
void solve() {
  int s = 1, tpp, o, p;
  while (s <= m) {
    tpp = s;
    crnt = edg[s].w;
    while (edg[tpp].w == edg[s].w) {
      o = getpar(edg[tpp].x);
      p = getpar(edg[tpp].y);
      if (o != p) {
        ans[edg[tpp].srt] = 1;
        merge(o, p, edg[tpp].w, edg[tpp].srt);
        merge(p, o, edg[tpp].w, edg[tpp].srt);
        mark[o] = mark[p] = 0;
      } else {
        ans[edg[tpp].srt] = 0;
      }
      tpp++;
    }
    for (int i = s; i < tpp; i++) {
      if (getpar(edg[i].x) != getpar(edg[i].y)) {
        o = getpar(edg[i].x);
        p = getpar(edg[i].y);
        t = 0;
        if (!mark[o]) dfs(o);
        t = 0;
        if (!mark[p]) dfs(p);
      }
    }
    for (int i = s; i < tpp; i++) {
      par[getpar(edg[i].x)] = getpar(edg[i].y);
    }
    s = tpp;
  }
}
int main() {
  memset(pre, 0, sizeof pre);
  memset(ans, 0, sizeof ans);
  memset(di, 0, sizeof di);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    par[i] = i;
  }
  for (int i = 1; i <= m; i++) {
    cin >> edg[i].x >> edg[i].y >> edg[i].w;
    edg[i].srt = i;
  }
  sort(edg + 1, edg + 1 + m, cmp);
  solve();
  for (int i = 1; i <= m; i++) {
    if (ans[i] == 0) {
      puts("none");
    } else if (ans[i] == 1) {
      puts("at least one");
    } else {
      puts("any");
    }
  }
  return (0);
}
