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 = 1e5 + 10;
const long long inf = 1e18;
const long long mod = 1e9 + 7;
int u[maxn], v[maxn], w[maxn];
vector<pair<int, int> > G[maxn];
vector<pair<int, int> > Gp[maxn];
vector<pair<int, int> > vc;
int mark[maxn];
int ans[maxn], par[maxn], sz[maxn], par2[maxn];
int tt, dp[maxn], d[maxn];
bool vis[maxn], mm[maxn];
int pp, qq;
int get_root(int x) {
  if (par[x] == x) return x;
  return par[x] = get_root(par[x]);
}
void merge(int x, int y) {
  int X = get_root(x);
  int Y = get_root(y);
  if (X == Y) {
    mark[X] = tt;
    return;
  }
  if (sz[X] >= sz[Y]) {
    par[Y] = X;
    sz[X] += sz[Y];
  } else {
    par[X] = Y;
    sz[Y] += sz[X];
  }
}
void dfs(int x) {
  vis[x] = 1;
  for (int j = 0; j != Gp[x].size(); j++) {
    if (vis[Gp[x][j].first] && !mm[Gp[x][j].second])
      dp[x] = min(dp[x], d[Gp[x][j].first]);
    if (!vis[Gp[x][j].first]) {
      d[Gp[x][j].first] = d[x] + 1;
      par2[Gp[x][j].first] = x;
      mm[Gp[x][j].second] = 1;
      dfs(Gp[x][j].first);
      dp[x] = min(dp[x], dp[Gp[x][j].first]);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m, p;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    par[i] = i;
    sz[i] = 1;
  }
  for (int i = 0; i != m; i++) {
    cin >> u[i] >> v[i] >> w[i];
    G[u[i]].push_back({v[i], w[i]});
    G[v[i]].push_back({u[i], w[i]});
    vc.push_back({w[i], i});
  }
  sort(vc.begin(), vc.end());
  for (int i = 0; i < vc.size(); i = i) {
    p = i + 1;
    memset(vis, 0, sizeof(vis));
    memset(mm, 0, sizeof(mm));
    memset(dp, 63, sizeof(dp));
    tt = 0;
    while (p < vc.size() && vc[p].first == vc[i].first) p++;
    for (int j = i; j < p; j++) {
      if (get_root(u[vc[j].second]) == get_root(v[vc[j].second])) {
        ans[vc[j].second] = 1;
      }
      if (ans[vc[j].second] != 1) {
        Gp[get_root(u[vc[j].second])].clear();
        Gp[get_root(v[vc[j].second])].clear();
      }
    }
    for (int j = i; j < p; j++) {
      if (ans[vc[j].second] != 1) {
        pp = get_root(u[vc[j].second]);
        qq = get_root(v[vc[j].second]);
        Gp[pp].push_back({qq, tt});
        Gp[qq].push_back({pp, tt});
        tt++;
      }
    }
    for (int j = i; j < p; j++) {
      if (!vis[get_root(u[vc[j].second])] && ans[vc[j].second] != 1) {
        d[get_root(u[vc[j].second])] = 0;
        dfs(get_root(u[vc[j].second]));
      }
    }
    for (int j = i; j < p; j++) {
      if (ans[vc[j].second] != 1) {
        pp = get_root(u[vc[j].second]);
        qq = get_root(v[vc[j].second]);
        if (par2[pp] == qq) {
          if (dp[pp] <= d[qq])
            ans[vc[j].second] = 2;
          else
            ans[vc[j].second] = 3;
        } else if (par2[qq] == pp) {
          if (dp[qq] <= d[pp])
            ans[vc[j].second] = 2;
          else
            ans[vc[j].second] = 3;
        } else {
          ans[vc[j].second] = 2;
        }
      }
    }
    for (int j = i; j < p; j++) {
      merge(u[vc[j].second], v[vc[j].second]);
    }
    i = p;
  }
  string d[] = {"none", "at least one", "any"};
  for (int i = 0; i != m; i++) {
    cout << d[--ans[i]] << endl;
  }
  return 0;
}
