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 int N = 100010;
struct Edge {
  int x, y, z, idx, ans;
  bool operator<(const Edge a) const { return z < a.z; }
} E[N];
bool vis[N];
int siz[N], son[N], tp[N], d[N], fa[N], df[N], pf[N], dfn[N], from[N];
int ea[N * 2], eb[N * 2], ec[N], ed[N * 2], ep[N * 2], idx, etot, f[N];
int find(int x) { return f[x] == x ? x : f[x] = find(f[x]); }
void addEdge(int x, int y, int z, int w) {
  etot++;
  ea[etot] = y;
  eb[etot] = ec[x];
  ec[x] = etot;
  ed[etot] = z;
  ep[etot] = w;
}
void dfs1(int x, int f) {
  siz[x] = 1;
  for (int i = ec[x]; i; i = eb[i]) {
    int y = ea[i];
    if (y == f) continue;
    d[y] = d[x] + 1;
    fa[y] = x;
    df[y] = ed[i];
    pf[y] = ep[i];
    dfs1(y, x);
    siz[x] += siz[y];
    if (siz[y] > siz[son[x]]) son[x] = y;
  }
}
void dfs2(int x, int f) {
  tp[son[x]] = tp[x];
  dfn[x] = ++idx;
  from[idx] = x;
  if (son[x] == 0) return;
  dfs2(son[x], x);
  for (int i = ec[x]; i; i = eb[i]) {
    int y = ea[i];
    if (y != f && y != son[x]) {
      tp[y] = y;
      dfs2(y, x);
    }
  }
}
struct SegmentTree {
  int sum[N << 2];
  bool tag[N << 2];
  void build(int x, int l, int r) {
    if (l == r) {
      sum[x] = df[from[l]];
      return;
    }
    int mid = (l + r) >> 1;
    build((x << 1), l, mid);
    build((x << 1 | 1), mid + 1, r);
    sum[x] = max(sum[(x << 1)], sum[(x << 1 | 1)]);
  }
  int query(int x, int l, int r, int L, int R) {
    if (l == L && r == R) return sum[x];
    int mid = (l + r) >> 1;
    if (R <= mid)
      return query((x << 1), l, mid, L, R);
    else if (L > mid)
      return query((x << 1 | 1), mid + 1, r, L, R);
    else
      return max(query((x << 1), l, mid, L, mid),
                 query((x << 1 | 1), mid + 1, r, mid + 1, R));
  }
  void modify(int x, int l, int r, int L, int R, int v) {
    if (sum[x] < v) return;
    if (l == L && r == R) {
      if (sum[x] == v) {
        tag[x] = 1;
        return;
      }
      int mid = (l + r) >> 1;
      if (sum[(x << 1)] >= v) modify((x << 1), l, mid, l, mid, v);
      if (sum[(x << 1 | 1)] >= v)
        modify((x << 1 | 1), mid + 1, r, mid + 1, r, v);
      return;
    }
    int mid = (l + r) >> 1;
    if (R <= mid)
      modify((x << 1), l, mid, L, R, v);
    else if (L > mid)
      modify((x << 1 | 1), mid + 1, r, L, R, v);
    else
      modify((x << 1), l, mid, L, mid, v),
          modify((x << 1 | 1), mid + 1, r, mid + 1, R, v);
  }
  void pushdown(int x, int l, int r) {
    if (l == r) {
      if (tag[x]) E[pf[from[l]]].ans = 2;
      return;
    }
    if (tag[x]) {
      if (sum[(x << 1)] == sum[x]) tag[(x << 1)] = 1;
      if (sum[(x << 1 | 1)] == sum[x]) tag[(x << 1 | 1)] = 1;
    }
    int mid = (l + r) >> 1;
    pushdown((x << 1), l, mid);
    pushdown((x << 1 | 1), mid + 1, r);
  }
} T;
int n;
int read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -f;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - 48;
    c = getchar();
  }
  return x * f;
}
int query(int x, int y) {
  int ans = 0;
  while (tp[x] != tp[y]) {
    if (d[tp[x]] < d[tp[y]]) swap(x, y);
    ans = max(ans, T.query(1, 1, n, dfn[tp[x]], dfn[x]));
    x = fa[tp[x]];
  }
  if (dfn[x] == dfn[y]) return ans;
  if (dfn[x] > dfn[y]) swap(x, y);
  ans = max(ans, T.query(1, 1, n, dfn[x] + 1, dfn[y]));
  return ans;
}
void modify(int x, int y, int v) {
  while (tp[x] != tp[y]) {
    if (d[tp[x]] < d[tp[y]]) swap(x, y);
    T.modify(1, 1, n, dfn[tp[x]], dfn[x], v);
    x = fa[tp[x]];
  }
  if (dfn[x] == dfn[y]) return;
  if (dfn[x] > dfn[y]) swap(x, y);
  T.modify(1, 1, n, dfn[x] + 1, dfn[y], v);
}
signed main() {
  n = read();
  int m = read();
  for (int i = 1; i <= m; ++i) {
    E[i].x = read(), E[i].y = read(), E[i].z = read();
    E[i].idx = i;
  }
  sort(E + 1, E + 1 + m);
  for (int i = 1; i <= n; ++i) f[i] = i;
  int cnt = 1, tmp = 0;
  while (tmp < n - 1) {
    int x = find(E[cnt].x), y = find(E[cnt].y);
    if (x != y) {
      vis[cnt] = 1;
      addEdge(E[cnt].x, E[cnt].y, E[cnt].z, E[cnt].idx);
      addEdge(E[cnt].y, E[cnt].x, E[cnt].z, E[cnt].idx);
      f[x] = y;
      tmp++;
    }
    cnt++;
  }
  fa[1] = tp[1] = 1;
  dfs1(1, 0);
  dfs2(1, 0);
  T.build(1, 1, n);
  for (int i = 1; i <= m; ++i) {
    E[E[i].idx].ans = 1;
    if (!vis[i]) {
      int tmp = query(E[i].x, E[i].y);
      if (E[i].z > tmp)
        E[E[i].idx].ans = 3;
      else {
        E[E[i].idx].ans = 2;
        modify(E[i].x, E[i].y, tmp);
      }
    }
  }
  T.pushdown(1, 1, n);
  for (int i = 1; i <= m; ++i)
    puts(E[i].ans == 1 ? "any" : (E[i].ans == 2 ? "at least one" : "none"));
  fclose(stdin);
  fclose(stdout);
  return 0;
}
