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.
/*
 *  for an edge weight w, if it is in some mst, then all edges with weight less than w must in the mst as well (provided they do not form a cycle)
 *  for some edges of weight x, it easy to know if they are in zero or more MST-s by adding all edges of weight less than x and keeping
 *  track of the connected components formed so far, when consider an edge, check which components it is joining
 *  and construct a new graph using this edges
 *  to know if this edge is present in all or some MST-s, we need to know if this edge a bridge or not 
 */
import java.io.*;
import java.util.*;

public class A {

	static Queue<pair>[] adjList;
	static int[] dfs_low, dfs_num, parent;
	static int  counter;
	static Queue<Integer> nodes;
	
	static class pair
	{
		int u,idx;
		pair(int a,int b){
			u=a;
			idx=b;
		}
		pair(int a,int b,int t){
			u=Math.min(a, b);
			idx=Math.max(a, b);
		}
	}

	static void findArtPointsAndBridges()	
	{
		counter=0;
		int []x=new int [nodes.size()];
		int id=0;
		
		while(!nodes.isEmpty()) {
			int i=nodes.poll();
			if(dfs_num[i] == 0)
				dfs(i);
			x[id++]=i;
		}
		
		for(int y:x)
		{
			dfs_num[y]=dfs_low[y]=parent[y]=0;
		}
	}
	
	static void dfs(int u)
	{
		dfs_num[u] = dfs_low[u] = ++counter;
		while(!adjList[u].isEmpty()) {
			pair p=adjList[u].poll();
			int v=p.u;
			int idx=p.idx;
			if(dfs_num[v] == 0)
			{
				parent[v] = u;
				
				dfs(v);
				
				if(dfs_low[v] > dfs_num[u])
					ans[idx]=1;
				dfs_low[u] = Math.min(dfs_low[v], dfs_low[u]);
			}
			else
				if(parent[u] != v)
					dfs_low[u] = Math.min(dfs_low[u], dfs_num[v]);
		}
	}
	static int []ans;
	
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter out = new PrintWriter(System.out);
		int n = sc.nextInt(), m = sc.nextInt();
		int[] node1 = new int[m], node2 = new int[m], cost = new int[m];
		ans = new int[m];
		Integer[] indices = new Integer[m];
		for (int i = 0; i < m; i++) {
			node1[i] = sc.nextInt() - 1;
			node2[i] = sc.nextInt() - 1;
			cost[i] = sc.nextInt();
			indices[i] = i;
			ans[i] = -1;
		}
		adjList=new LinkedList[n];
		nodes=new LinkedList();
		dfs_low=new int [n];
		dfs_num=new int [n];
		parent=new int [n];
		for(int i=0;i<n;i++) {
			adjList[i]=new LinkedList();
		}
		DSU dsu = new DSU(n);
		
		Arrays.sort(indices, Comparator.comparingInt(i -> cost[i]));
		// 0 = none 1=all 2=at least one
		TreeMap<pair,Integer> cnt=new TreeMap<>((x,y)->x.u!=y.u?x.u-y.u:x.idx-y.idx);

		for (int l = 0; l < m;) {
			int r = l;
			while (r < m && cost[indices[r]] == cost[indices[l]]) {
				int idx=indices[r];
				int u = dsu.findSet(node1[idx]), v = dsu.findSet(node2[idx]);
				node1[idx]=u;
				node2[idx]=v;

				if (u==v)
					ans[idx] = 0;
				else
				{
					adjList[u].add(new pair(v, idx));
					adjList[v].add(new pair(u, idx));
					nodes.add(u);
					nodes.add(v);		
					pair pair=new pair(u,v,1);
					cnt.put(pair, cnt.getOrDefault(pair, 0)+1);
				}
				
				
				r++;
			}
			r = l;
			findArtPointsAndBridges();
			while (r < m && cost[indices[r]] == cost[indices[l]]) {
				int idx=indices[r];
				int u = node1[idx], v = node2[idx];
				
				if(u!=v) {
					pair pair=new pair(u,v,1);
					if(cnt.get(pair)>1)
						ans[idx]=2;
									
				}
				r++;
			}
			

			while (l < r) {
				int idx=indices[l];
				int u=node1[idx],v=node2[idx];
				pair pair=new pair(u,v,1);
				cnt.put(pair, 0);
				dsu.union(u, v);
				l++;
			}

		}
		for (int x : ans)
			out.println(x == 0 ? "none" : x == 1 ? "any" : "at least one");
		out.close();

	}
	
	static class DSU {
		int[] p, r;

		DSU(int n) {
			p = new int[n];
			r = new int[n];
			for (int i = 0; i < n; i++)
				p[i] = i;
		}

		int findSet(int x) {
			if (p[x] == x)
				return x;
			else
				return p[x] = findSet(p[x]);
		}

		boolean isSameSet(int x, int y) {
			return findSet(x) == findSet(y);
		}

		boolean union(int x, int y) {
			x = findSet(x);
			y = findSet(y);
			if (x == y)
				return false;
			if (r[x] > r[y])
				p[y] = x;
			else {
				p[x] = y;
				if (r[x] == r[y])
					r[y]++;
			}

			return true;
		}
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		Scanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws NumberFormatException, IOException {
			return Double.parseDouble(next());
		}
	}
}
