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.
/*
Solution: Use Kruskal's algorithm (DSU) to make the MST. Handle all edges with the same weight at
one time, making a separate graph with the DSU sets the edges connect. If the edge is a bridge in
this new graph, then it's used in all MSTs; otherwise it's used in at least one MST. If an edge
connects a set to itself, then it's useless / is not included in any MST.
Runtime: O(M * log(M))
*/

import java.util.*;
import java.io.*;

@SuppressWarnings("unchecked")
public class mstedges {
    final int MAXW = 1000001;
    int N, M;
    int[] answers;
    ArrayList<Edge>[] edges;
    DisjointSet ds;

    mstedges(BufferedReader in, PrintWriter out) throws IOException {
        StringTokenizer st = new StringTokenizer(in.readLine());
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        edges = new ArrayList[MAXW];
        for (int i = 0; i < MAXW; i++) edges[i] = new ArrayList<>(2);
        int a, b, w;
        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(in.readLine());
            a = Integer.parseInt(st.nextToken()) - 1;
            b = Integer.parseInt(st.nextToken()) - 1;
            w = Integer.parseInt(st.nextToken());
            edges[w].add(new Edge(a, b, w, i));
        }

        // Evaluate edges in order
        answers = new int[M];
        ds = new DisjointSet(N);
        for (int i = 0; i < MAXW; i++) {
            if (edges[i].size() != 0) evalStage(edges[i]);
        }

        for (int ans : answers) {
            if (ans == 0) out.println("any");
            else if (ans == 1) out.println("at least one");
            else out.println("none");
        }
    }

    void evalStage(ArrayList<Edge> edges) {
        int tempN = 0;
        HashMap<Integer, Integer> setToI = new HashMap<>();
        // Create a new graph
        for (Edge e : edges) {
            int setA = ds.find(e.a);
            int setB = ds.find(e.b);
            e.a = setA;
            e.b = setB;
            if (!setToI.containsKey(setA)) {
                setToI.put(setA, tempN++);
            }
            if (!setToI.containsKey(setB)) {
                setToI.put(setB, tempN++);
            }
        }

        adj = new ArrayList[tempN];
        for (int i = 0; i < tempN; i++) adj[i] = new ArrayList<>(2);
        int numEdges = 0;
        for (Edge e : edges) {
            // System.out.println(e.a + " " + e.b);
            // Actually merge them now
            ds.union(e.a, e.b);
            e.a = setToI.get(e.a);
            e.b = setToI.get(e.b);
            if (e.a == e.b) {
                // Connects same set; will never be used
                answers[e.origI] = 2;
            } else {
                // Add to temp graph
                adj[e.a].add(new TempEdge(e.b, numEdges, e.origI));
                adj[e.b].add(new TempEdge(e.a, numEdges++, e.origI));
            }
        }

        // Find bridges in this graph
        usedEdge = new boolean[numEdges];
        disc = new int[tempN];
        ll = new int[tempN];
        currDisc = 1;
        for (int i = 0; i < tempN; i++) findBridges(i);
    }

    int currDisc = 1;
    ArrayList<TempEdge>[] adj;
    int[] disc, ll;
    boolean[] usedEdge;
    void findBridges(int n) {
        disc[n] = currDisc++;
        ll[n] = disc[n];
        for (TempEdge e : adj[n]) {
            if (usedEdge[e.i]) continue;
            usedEdge[e.i] = true;
            if (disc[e.n] == 0) {
                // Node not yet visited
                findBridges(e.n);
                if (ll[e.n] > disc[n]) {
                    // This is a bridge
                    answers[e.origI] = 0;
                    // System.out.println(e.origI + " bridge");
                } else {
                    // Not a bridge
                    answers[e.origI] = 1;
                }
                ll[n] = Math.min(ll[e.n], ll[n]);
            } else {
                // Node already visited (not a bridge)
                answers[e.origI] = 1;
                ll[n] = Math.min(disc[e.n], ll[n]);
            }
        }
    }

    class TempEdge {
        int n, i, origI;
        TempEdge(int n, int i, int origI) {
            this.n = n;
            this.i = i;
            this.origI = origI;
        }
    }

    class Edge {
        int a, b, w, origI;
        Edge(int a, int b, int w, int origI) {
            this.a = a;
            this.b = b;
            this.w = w;
            this.origI = origI;
        }
    }

    class DisjointSet {
        int size;
        int[] vals;

        DisjointSet(int size) {
            this.size = size;
            vals = new int[size];
            Arrays.fill(vals, -1);
        }

        void union(int a, int b) {
            int setA = find(a);
            int setB = find(b);
            if (setA == setB) return;

            if (vals[setA] < vals[setB]) {
                vals[setA] += vals[setB];
                vals[setB] = setA;
            } else {
                vals[setB] += vals[setA];
                vals[setA] = setB;
            }
        }

        int find(int i) {
            if (vals[i] < 0) return i;
            else {
                int res = find(vals[i]);
                vals[i] = res;
                return res;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
        // BufferedReader in = new BufferedReader(new FileReader("mstedges.in"));
        // PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("mstedges.out")));
        new mstedges(in, out);
        in.close();
        out.close();
    }
}
