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>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimization("unroll-loops")
#pragma GCC optimization("O3")
using namespace std;
const int N = 1e6 + 10, LOG = 26, M = 1e5;
vector<vector<pair<int, pair<int, int>>>> edge;
vector<vector<int>> graph;
int U[N];
int V[N];
bool isce[N];
int tme, vis[N], arr[N], sz[N], par[N], value[N];
int findPar(int v) {
  if (v == par[v]) return v;
  return par[v] = findPar(par[v]);
}
void merge(int a, int b) {
  a = findPar(a);
  b = findPar(b);
  if (a != b) {
    if (sz[a] < sz[b]) swap(a, b);
    par[b] = a;
    sz[a] += sz[b];
  }
}
int adj(int u, int e) { return U[e] == u ? V[e] : U[e]; }
int dfs(int u, int edge) {
  vis[u] = 1;
  arr[u] = tme++;
  int dbe = arr[u];
  for (auto e : graph[u]) {
    int w = adj(u, e);
    if (!vis[w])
      dbe = min(dbe, dfs(w, e));
    else if (e != edge)
      dbe = min(dbe, arr[w]);
  }
  if (dbe == arr[u] && edge != -1) isce[edge] = 1;
  return dbe;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) par[i] = i, sz[i] = 1;
  edge.resize(N);
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    edge[w].push_back({i, {u, v}});
  }
  for (int i = 1; i < N; i++) {
    if (edge[i].size() == 0) continue;
    set<int> cg;
    set<int> ce;
    for (auto u : edge[i]) {
      if (findPar(u.second.first) == findPar(u.second.second))
        value[u.first] = 2;
      if (value[u.first] != 2) {
        ce.insert(u.first);
        cg.insert(findPar(u.second.second));
        cg.insert(findPar(u.second.first));
      }
    }
    if (cg.size() == 0) continue;
    graph.resize(cg.size());
    map<int, int> mg;
    vector<int> vg;
    map<int, int> me;
    vector<int> ve;
    vg.resize(cg.size());
    ve.resize(ce.size());
    int cnt = 0;
    for (auto it = cg.begin(); it != cg.end(); it++) {
      mg[(*it)] = cnt;
      vg[cnt] = (*it);
      cnt++;
    }
    cnt = 0;
    for (auto it = ce.begin(); it != ce.end(); it++) {
      me[(*it)] = cnt;
      ve[cnt] = (*it);
      cnt++;
    }
    for (auto u : edge[i]) {
      if (value[u.first] == 2) continue;
      graph[mg[par[u.second.first]]].push_back(me[u.first]);
      graph[mg[par[u.second.second]]].push_back(me[u.first]);
      U[me[u.first]] = mg[par[u.second.first]];
      V[me[u.first]] = mg[par[u.second.second]];
    }
    for (int i = 0; i < cg.size(); i++)
      if (!vis[i]) dfs(i, -1);
    for (int k = 0; k < ce.size(); k++)
      if (isce[k] == 1)
        value[ve[k]] = 0;
      else
        value[ve[k]] = 1;
    tme = 0;
    for (int k = 0; k < cg.size(); k++) {
      vis[k] = 0;
      arr[k] = 0;
    }
    graph.clear();
    for (int k = 0; k < ce.size(); k++) {
      isce[k] = 0;
      U[k] = 0;
      V[k] = 0;
    }
    for (auto u : edge[i]) merge(u.second.first, u.second.second);
  }
  for (int i = 0; i < m; i++) {
    if (value[i] == 0) cout << "any\n";
    if (value[i] == 1) cout << "at least one\n";
    if (value[i] == 2) cout << "none\n";
  }
}
