// Arup Guha
// Started: a long time ago
// 7/5/2015
// Solution to 2014 South East Regional D1 Problem A: Alchemy

import java.util.*;

public class alchemy {

	public static circle[] saveCircles;
	public static circle[] myCircles;
	public static circleTree[] myNodes;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int numCircles = stdin.nextInt();

		// Read in circles.
		myCircles = new circle[numCircles+1];
		saveCircles = new circle[numCircles+1];
		myCircles[0] = new circle(0, 0, 0, 100000, 0, 0);
		saveCircles[0] = myCircles[0];
		for (int i=1; i<=numCircles; i++) {
			int x = stdin.nextInt();
			int y = stdin.nextInt();
			int r = stdin.nextInt();
			int a = stdin.nextInt();
			int b = stdin.nextInt();
			myCircles[i] = new circle(i, x, y, r, a, b);
			saveCircles[i] = myCircles[i];
		}

		// Sort these, so we can form our tree.
		Arrays.sort(myCircles);

		// Make these nodes, so we can start making our tree.
		myNodes = new circleTree[numCircles+1];
		for (int i=0; i<=numCircles; i++)
			myNodes[i] = new circleTree(myCircles[i]);

		// Place each circle in the tree structure.
		for (int i=0; i<=numCircles; i++) {

			// Get this circle's parent, if any.
			int parent = -1;
			for (int j=i-1; j>=0; j--) {
				if (myCircles[i].in(myCircles[j])) {
					parent = j;
					break;
				}
			}

			// Add link or note that this is a root node.
			if (parent != -1) 	myNodes[parent].addKid(myNodes[i]);
		}

		// Calculate some useful information and get the maximal result.
		myNodes[0].setDepth(-1);
		myNodes[0].setAncestors();
		long total = myNodes[0].solve();

		// Useful for getting a lexicographically first list.
		Arrays.sort(myNodes);


		// This will keep our list.
		ArrayList<Integer> order = new ArrayList<Integer>();
		boolean[] used = new boolean[numCircles+1];

		// Until it's filled.
		while (order.size() != numCircles) {

			// Store all possible next values.
			int[] next = new int[2001];
			int cnt = 0;
			for (int i=1; i<numCircles+1; i++)
				if (!used[i] && myNodes[i].pts == myNodes[i].node.bestScore(myNodes[i].depth)) next[cnt++]=i;

			boolean found = false;
			int maybe = 0;

			// Keep on going until we find the first possible candidate that doesn't screw up anything later.
			for (int i=0; i<cnt; i++) {

				// Next item to try.
				maybe = next[i];
				boolean ok = true;

				// See if this item messes up a future item.
				for (int j=0; j<cnt; j++) {
					int x = next[j];
					if (x == maybe) continue;
					if (myNodes[x].curDepth == myNodes[x].minDepth && myNodes[x].ancestors.get(maybe)) {
						ok = false;
						break;
					}
				}

				// If not, we've found what we want.
				if (ok) found = true;
				if (found) break;
			}

			// Add this.
			order.add(maybe);
			used[maybe] = true;

			// Update the nodes that are children of maybe to indicate their new current points and depth.
			for (int i=1; i<numCircles+1; i++) {
				if (myNodes[i].ancestors.get(maybe)) {
					if (myNodes[i].curDepth%2 == 1) myNodes[i].pts -= myNodes[i].node.fireToWater;
					else				 			myNodes[i].pts -= myNodes[i].node.waterToFire;
					myNodes[i].curDepth--;
				}
			}
		}

		// Print result.
		System.out.println(total);
		for (int i=0; i<order.size()-1; i++)
			System.out.print(order.get(i)+" ");
		System.out.println(order.get(order.size()-1));
	}
}

class circle implements Comparable<circle> {

	public int ID;
	public int x;
	public int y;
	public int r;
	public int fireToWater;
	public int waterToFire;
	public boolean isFire;

	public circle(int myID, int myX, int myY, int myR, int a, int b) {
		ID = myID;
		x = myX;
		y = myY;
		r = myR;
		fireToWater = a;
		waterToFire = b;
		isFire = true;
	}

	public int compareTo(circle other) {
		return other.r - this.r;
	}

	// Returns the best score for this circle at the given depth.
	public long bestScore(int depth) {

		// This is clear.
		if (depth <= 0) return 0;

		// We want to take all points.
		if (fireToWater >=0 && waterToFire >= 0)
			return (depth+1)/2*fireToWater + depth/2*waterToFire;

		// Tricky case, going up and down, but non-negative cycles of 2.
		if (fireToWater >= 0 && waterToFire < 0 && fireToWater + waterToFire >= 0) {
			if (depth%2 == 0) return depth/2*fireToWater + (depth/2-1)*waterToFire;
			else			  return (depth+1)/2*fireToWater + depth/2*waterToFire;
		}

		// Want complete cycles of length 2.
		if (fireToWater < 0 && fireToWater+waterToFire >= 0)
			return depth/2*(fireToWater+waterToFire);

		// Just want one transmutation.
		if (fireToWater >= 0)
			return fireToWater;

		// None if we get all the way here.
		return 0;
	}

	// Returns the minimum depth this circle can achieve it's max score <= depth.
	public int getMinDepth(int depth) {
		if (depth == 0) return 0;

		// Deal with first number positive - either we use full depth, depth-1 or 1, depending
		// on whether waterToFire is +, 0, - (and how far -)
		if (fireToWater > 0) {
			if (waterToFire > 0)  return depth;
			if (fireToWater+waterToFire > 0) return depth%2 == 1 ? depth : depth-1;
			return 1;
		}

		// fireToWater makes no difference, so result is based on waterToFire.
		if (fireToWater == 0) {
			if (waterToFire > 0) return depth%2 == 0 ? depth : depth-1;
			if (waterToFire <= 0) return 0;
		}

		// Must have max # of even cycles here.
		if (fireToWater + waterToFire > 0) return depth%2 == 0 ? depth : depth-1;

		// If we get here, depth 0 gets us a maximal score (of 0).
		return 0;
	}

	// Note: This works since no circles intersect.
	public boolean in(circle bigger) {
		return r < bigger.r && distSq(bigger) <= bigger.r*bigger.r;
	}

	public int distSq(circle other) {
		return (this.x-other.x)*(this.x-other.x) + (this.y-other.y)*(this.y-other.y);
	}
}

class circleTree implements Comparable<circleTree> {

	public circle node;
	public ArrayList<circleTree> kids;
	public int depth;
	public int curDepth;
	public long pts;
	public int minDepth;
	public BitSet ancestors;

	public circleTree(circle item) {
		node = item;
		kids = new ArrayList<circleTree>();
		ancestors = new BitSet(2001);
	}

	public int compareTo(circleTree other) {
		return this.node.ID - other.node.ID;
	}

	public void addKid(circleTree myKid) {
		kids.add(myKid);
	}

	// Set's the depth of this node to d (and some other info), and recursively sets all nodes below it.
	public void setDepth(int d) {
		depth = d;
		curDepth = depth;
		pts = (depth+1)/2*node.fireToWater + depth/2*node.waterToFire;
		minDepth = node.getMinDepth(depth);
		for (int i=0; i<kids.size(); i++)
			kids.get(i).setDepth(d+1);
	}

	// Sets up ancestors for this node.
	public void setAncestors() {
		for (int i=0; i<kids.size(); i++) {
			kids.get(i).ancestors = (BitSet)ancestors.clone();
			kids.get(i).ancestors.set(node.ID);
		}
		for (int i=0; i<kids.size(); i++) {
			kids.get(i).setAncestors();
		}
	}

	public long solve() {

		// Set up search for insertion location for this node into res.
		long value = node.bestScore(depth);

		// Add up all the scores of the kids.
		for (int i=0; i<kids.size(); i++)
			value += kids.get(i).solve();

		// This is the best score we can get.
		return value;
	}
}