This problem uses a simplified network topology model, please read the problem statement carefully and use it as a formal document as you develop the solution.

Polycarpus continues working as a system administrator in a large corporation. The computer network of this corporation consists of n computers, some of them are connected by a cable. The computers are indexed by integers from 1 to n. It's known that any two computers connected by cable directly or through other computers

Polycarpus decided to find out the network's topology. A network topology is the way of describing the network configuration, the scheme that shows the location and the connections of network devices.

Polycarpus knows three main network topologies: bus, ring and star. A bus is the topology that represents a shared cable with all computers connected with it. In the ring topology the cable connects each computer only with two other ones. A star is the topology where all computers of a network are connected to the single central node.

Let's represent each of these network topologies as a connected non-directed graph. A bus is a connected graph that is the only path, that is, the graph where all nodes are connected with two other ones except for some two nodes that are the beginning and the end of the path. A ring is a connected graph, where all nodes are connected with two other ones. A star is a connected graph, where a single central node is singled out and connected with all other nodes. For clarifications, see the picture.

<image> (1) — bus, (2) — ring, (3) — star

You've got a connected non-directed graph that characterizes the computer network in Polycarpus' corporation. Help him find out, which topology type the given network is. If that is impossible to do, say that the network's topology is unknown. 

Input

The first line contains two space-separated integers n and m (4 ≤ n ≤ 105; 3 ≤ m ≤ 105) — the number of nodes and edges in the graph, correspondingly. Next m lines contain the description of the graph's edges. The i-th line contains a space-separated pair of integers xi, yi (1 ≤ xi, yi ≤ n) — the numbers of nodes that are connected by the i-the edge.

It is guaranteed that the given graph is connected. There is at most one edge between any two nodes. No edge connects a node with itself.

Output

In a single line print the network topology name of the given graph. If the answer is the bus, print "bus topology" (without the quotes), if the answer is the ring, print "ring topology" (without the quotes), if the answer is the star, print "star topology" (without the quotes). If no answer fits, print "unknown topology" (without the quotes).

Examples

Input

4 3
1 2
2 3
3 4


Output

bus topology


Input

4 4
1 2
2 3
3 4
4 1


Output

ring topology


Input

4 3
1 2
1 3
1 4


Output

star topology


Input

4 4
1 2
2 3
3 1
1 4


Output

unknown topology
import java.io.*;
import java.math.*;
import java.util.*;

/**
 *
 * @author Saju
 *
 */

public class Main {

	private static int dx[] = { -2, -3, -2, -1, -1, 1};
	private static int dy[] = { 1, -1, -1, -2, -3, -2};

	private static final long INF = (long) (1e15);
	private static final long NEG_INF = Long.MIN_VALUE;
	private static final double EPSILON = 1e-10;

	private static final int MAX = 1007;
	private static final int MOD = 10007;
	
	private static final int MAXN = 100007;
	private static final int MAXA = 1000009;
	private static final int MAXLOG = 22;

	public static void main(String[] args) {

		InputReader in = new InputReader(System.in);
		PrintWriter out = new PrintWriter(System.out);
		

/*


*/
		
		int n = in.nextInt();
		int m = in.nextInt();
		List<Integer> adj[] = new ArrayList[n];
		for(int i = 0; i < n; i++) {
			adj[i] = new ArrayList<Integer>();
		}
		for(int i = 0; i < m; i++) {
			int u = in.nextInt();
			int v = in.nextInt();
			u--;
			v--;
			adj[u].add(v);
			adj[v].add(u);
			
		}
		
		LinkedList<Integer> queue = new LinkedList<Integer>();
		boolean visited[] = new boolean[n];
		int childs[] = new int[n];
		for(int i = 0; i < n; i++) {
			childs[i] = adj[i].size();
		}
		// bus check
		boolean firstOne = false;
		boolean secondOne = false;
		boolean isBus = true;
		for(int i = 0; i < n; i++) {
			if(childs[i] > 2) {
				isBus = false;
				break;
			}
			else if(childs[i] == 1 && !firstOne) {
				firstOne = true;
			}
			else if(childs[i] == 1 && firstOne && !secondOne) {
				secondOne = true;
			}
			else if(childs[i] == 1 && firstOne && secondOne) {
				isBus = false;
				break;
			}
		}
		if(isBus && firstOne && secondOne) {
			System.out.println("bus topology");
			return;
		}

		// ring check
		boolean isRing = true;
		for(int i = 0; i < n; i++) {
			if(childs[i] != 2) {
				isRing = false;
				break;
			}
		}
		if(isRing) {
			System.out.println("ring topology");
			return;
		}
		
		// star check
		
		boolean isStar = true;
		int oneCount = 0;
		int oneLess = 0;
		for(int i = 0; i < n; i++) {
			
			if(childs[i] != n - 1 && childs[i] != 1){
				isStar = false;
				break;
			}
			if(childs[i] == n - 1) {
				oneLess++;
			}
			else if(childs[i] == 1) {
				oneCount++;
			}
		}
//		System.out.println(isStar + " " + oneCount + " " + oneLess);
		if(isStar && oneCount == n -1 && oneLess == 1) {
			System.out.println("star topology");
			return;
		}
		
		System.out.println("unknown topology");
		
		out.flush();
		out.close();
		System.exit(0);
	}

	
	private static class Pair<T>{
		T a;
		T b;
		Pair(T a, T b){
			this.a = a;
			this.b = b;
		}
	}
	
	private static class SegmentTree{
		int n;
		private final int MAXN = 100007;
		private long[] tree = new long[MAXN << 2];
		private long[] lazy = new long[MAXN << 2];
		private long[] arr = new long[MAXN];
		
		
		/***
		 * 
		 * arr is 1 based index.
		 * 
		 * @param arr
		 * 
		 */
		SegmentTree(int n, long[] arr){
			this.n = n;
			for(int i = 0; i < arr.length; i++) {
				this.arr[i] = arr[i];
			}
		}
		
		void build(int index, int left, int right) {
			if(left == right) {
				tree[index] = arr[left];
			}
			else {
				int mid = (left + right) / 2;
				
				build(index * 2, left, mid);
				build((index * 2) + 1, mid + 1, right);
				tree[index] = max(tree[(index * 2)], tree[(index * 2) + 1]);
			}
		}
		
		long query(int node, int left, int right, int start, int end) {
			
			if(left > end || right < start) {
				return NEG_INF;
			}
			
			if(left >= start && right <= end) {
				return tree[node];
			}
			int mid = (left + right) / 2;
			long val1 = query(2 * node, left, mid, start, end);
			long val2 = query(2 * node + 1, mid + 1, right, start, end);
			
			return max(val1, val2);
		}
		
		void update(int node, int left, int right, int idx, long val) {
			if(left == right) {
				tree[node] += val;
			}
			else {
				int mid = (left + right) / 2;
				if(idx <= mid) {
					update(2 * node, left, mid, idx, val);
				}
				else {
					update(2 * node + 1, mid + 1, right, idx, val);
				}
				tree[node] = max(tree[(2 * node) + 1], tree[(2 * node)]);
			}
		}
		
		

		 void updateRange(int node, int start, int end, int l, int r, long val)
		{
		    if(lazy[node] != 0)
		    { 
		        // This node needs to be updated
		        tree[node] =  lazy[node];    // Update it
		        if(start != end)
		        {
		            lazy[node*2] = lazy[node];                  // Mark child as lazy
		            lazy[node*2+1] = lazy[node];                // Mark child as lazy
		        }
		        lazy[node] = 0;                                  // Reset it
		    }
		    if(start > end || start > r || end < l)              // Current segment is not within range [l, r]
		        return;
		    if(start >= l && end <= r)
		    {
		        // Segment is fully within range
		        tree[node] =  val;
		        if(start != end)
		        {
		            // Not leaf node
		            lazy[node*2] = val;
		            lazy[node*2+1] = val;
		        }
		        return;
		    }
		    int mid = (start + end) / 2;
		    updateRange(node*2, start, mid, l, r, val);        // Updating left child
		    updateRange(node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
		    tree[node] = max(tree[node*2], tree[node*2+1]);        // Updating root with max value 
		}

		 long queryRange(int node, int start, int end, int l, int r)
		{
		    if(start > end || start > r || end < l)
		        return 0;         // Out of range
		    if(lazy[node] != 0)
		    {
		        // This node needs to be updated
		        tree[node] =  lazy[node];            // Update it
		        if(start != end)
		        {
		            lazy[node*2] = lazy[node];         // Mark child as lazy
		            lazy[node*2+1] = lazy[node];    // Mark child as lazy
		        }
		        lazy[node] = 0;                 // Reset it
		    }
		    if(start >= l && end <= r)             // Current segment is totally within range [l, r]
		        return tree[node];
		    int mid = (start + end) / 2;
		    long p1 = queryRange(node*2, start, mid, l, r);         // Query left child
		    long p2 = queryRange(node*2 + 1, mid + 1, end, l, r); // Query right child
		    return max(p1, p2);
		}
		
		 void buildRange(int node, int low, int high){
			if(low == high){
				tree[node] =  arr[low];
				return;
			}
			
			int mid = (low + high) / 2;
			int left = node << 1;
			int right = left | 1;
			buildRange(left, low, mid);
			buildRange(right, mid + 1, high);
			tree[node] = max(tree[left], tree[right]);
		}
		
		
		void printSegmentTree() {
			System.out.println(Arrays.toString(tree));
		}
		
	}
	
	private static class KMP{
		
		private static char[] t;
		private static char[] s;
		
		public int kmp(char[]t, char[]s) {
			this.t = t;
			this.s = s;
			return this.kmp();
		}
		
		private int kmp() {
			
			List<Integer> prefixTable = getPrefixTable(s);
			
			int match = 0;
			int i = 0;
			int j = 0;
			
			int n = t.length;
			int m = s.length;
			while(i < n) {
				if(t[i] == s[j]) {
					if(j == m - 1) {
						match++;
						j = prefixTable.get(j - 1);
						continue;
					}
					i++;
					j++;
				}
				else if(j > 0) {
					j = prefixTable.get(j - 1);
				}
				else {
					i++;
				}
			}
			
			return match;
		}

		/***
		1. We compute the prefix values π[i] in a loop by iterating 	<br/>
				from i=1 to i=n−1 (π[0] just gets assigned with 0).		<br/><br/>
		2. To calculate the current value π[i] we set the variable j 	<br/>
				denoting the length of the best suffix for i−1. Initially j=π[i−1].	<br/>
		3. Test if the suffix of length j+1 is also a prefix by		 <br/><br/>
				comparing s[j] and s[i]. If they are equal then we assign π[i]=j+1, 	<br/>
				otherwise we reduce j to π[j−1] and repeat this step.		<br/><br/>
		4. If we have reached the length j=0 and still don't have a match,	<br/> 
				then we assign π[i]=0 and go to the next index i+1.		<br/><br/>
				
		@param
	 	pattern(String)
	***/
		private List<Integer> getPrefixTable(char[] pattern){
			
			List<Integer> prefixTable = new ArrayList<Integer>();
			int n = pattern.length;
			for(int i = 0; i < n; i++) {
				prefixTable.add(0);
			}
			
			for(int i = 1; i < n; i++) {
				for(int j = prefixTable.get(i - 1); j >= 0;) {
					if(pattern[j] == pattern[i]) {
						prefixTable.set(i, j + 1);
						break;
					}
					else if(j > 0){
						j = prefixTable.get(j - 1);
					}
					else {
						break;
					}
				}
			}
			
			return prefixTable;
		}
	}
	


	private static class Point {
		long x;
		long y;
		Point(long x, long y){
			this.x = x;
			this.y = y;
		}
		
		@Override
		public boolean equals(Object obj) {
			Point ob = (Point) obj;
			if(this.x == ob.x && this.y == ob.y){
				return true;
			}
			return false;
		}
		@Override
		public String toString() {
			return this.x + " " + this.y;
		}
	}

	private static int log(int x, int base) {
		return (int) (Math.log(x) / Math.log(base));
	}

	private static long max(long a, long b) {
		if (a >= b) {
			return a;
		}
		return b;
	}

	private static long abs(long a) {
		if (a < 0) {
			return -a;
		}
		return a;
	}

	private static int abs(int a) {
		if (a < 0) {
			return -a;
		}
		return a;
	}

	private static int max(int a, int b) {
		if (a >= b) {
			return a;
		}
		return b;
	}

	private static int min(int a, int b) {
		if (a <= b) {
			return a;
		}
		return b;
	}
	
	private static long min(long a, long b) {
		if (a <= b) {
			return a;
		}
		return b;
	}

	private static long gcd(long a, long b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	private static int gcd(int a, int b) {
		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	private static long bigMod(long n, long k, long m) {

		long ans = 1;
		while (k > 0) {
			if ((k & 1) == 1) {
				ans = (ans * n) % m;
			}
			n = (n * n) % m;
			k >>= 1;
		}
		return ans;
	}

	/*
	 * Returns an iterator pointing to the first element in the range [first,
	 * last] which does not compare less than val.
	 * 
	 */
	private static int lowerBoundNew(long[] arr, long num) {
		int start = 0;
		int end = arr.length - 1;
		int index = 0;
		int len = arr.length;
		int mid = 0;
		while (true) {
			if (start > end) {
				break;
			}
			mid = (start + end) / 2;
			if (arr[mid] > num) {
				end = mid - 1;
			} else if (arr[mid] < num) {
				start = mid + 1;
			} else {
				while (mid >= 0 && arr[mid] == num) {
					mid--;
				}
				return mid + 1;
			}
		}
		if (arr[mid] < num) {
			return mid + 1;
		}
		return mid;
	}

	/*
	 * upper_bound() is a standard library function in C++ defined in the header
	 * . It returns an iterator pointing to the first element in the range
	 * [first, last) that is greater than value, or last if no such element is
	 * found
	 * 
	 */
	private static int upperBoundNew(long[] arr, long num) {

		int start = 0;
		int end = arr.length - 1;
		int index = 0;
		int len = arr.length;
		int mid = 0;
		while (true) {
			if (start > end) {
				break;
			}
			mid = (start + end) / 2;
			if (arr[mid] > num) {
				end = mid - 1;
			} else if (arr[mid] < num) {
				start = mid + 1;
			} else {
				while (mid < len && arr[mid] == num) {
					mid++;
				}
				if (mid == len - 1 && arr[mid] == num) {
					return mid + 1;
				} else {
					return mid;
				}
			}
		}
		if (arr[mid] < num) {
			return mid + 1;
		}
		return mid;
	}

	private static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream));
			tokenizer = null;
		}

		public String next() {
			try {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					tokenizer = new StringTokenizer(reader.readLine());

				}
			} catch (IOException e) {
				return null;
			}
			return tokenizer.nextToken();
		}

		public String nextLine() {
			String line = null;
			try {
				tokenizer = null;
				line = reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			return line;
		}

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

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public boolean hasNext() {
			try {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					tokenizer = new StringTokenizer(reader.readLine());
				}
			} catch (Exception e) {
				return false;
			}
			return true;
		}
	}
}
  	 	 	   			  		  			   				 	