import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Locale;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		new Thread(null, new Runnable() {
			public void run() {
				try {
					long prevTime = System.currentTimeMillis();
					new Main().run();
					System.err.println("Total time: "
							+ (System.currentTimeMillis() - prevTime) + " ms");
					System.err.println("Memory status: " + memoryStatus());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}, "1", 1L << 24).start();
	}

	void run() throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		Object o = solve();
		if (o != null)
			out.println(o);
		out.close();
		in.close();
	}

	int n;
	Point[] ps;
	int[] dp;

	private Object solve() throws IOException {
		int o_x = ni();
		int o_y = ni();

		n = ni();
		ps = new Point[n];
		for (int i = 0; i < n; i++)
			ps[i] = new Point(ni() - o_x, ni() - o_y);

		dp = new int[1 << n];
		Arrays.fill(dp, Integer.MAX_VALUE);
		dp[0] = 0;
		int[] path_x = new int[1 << n];
		int[] path_y = new int[1 << n];

		for (int mask = 1; mask < (1 << n); mask++) {
			int i = min(mask);
			int min_val = dp[mask - (1 << i)] + 2 * ps[i].norm;
			if (min_val < dp[mask]) {
				dp[mask] = min_val;
				path_x[mask] = i;
				path_y[mask] = i;

			}
			for (int j = i + 1; j < n; j++)
				if ((mask & (1 << j)) != 0) {
					int newMask = mask - (1 << i) - (1 << j);
					int val = dp[newMask] + ps[i].norm + ps[j].norm
							+ ps[i].dist(ps[j]);
					if (val < dp[mask]) {
						dp[mask] = val;
						path_x[mask] = i;
						path_x[mask] = j;

					}
				}
		}
		pln(dp[(1 << n) - 1]);

		int maskPath = (1 << n) - 1;
		LinkedList<Long> list = new LinkedList<Long>();
		while (maskPath != 0) {
			long x = path_x[maskPath];
			long y = path_y[maskPath];

			list.addFirst(0L);
			list.addFirst(y + 1);
			maskPath -= (1 << y);
			if (x != y) {
				list.addFirst(x + 1);
				maskPath -= 1 << x;
			}
		}
		list.addFirst(0L);
		show(list);
		return null;
	}

	private int min(int mask) {
		int ret = 0;
		while (mask % 2 == 0) {
			mask /= 2;
			ret++;
		}
		return ret;
	}

	private void show(LinkedList<Long> list) {
		int index = 0;
		for (long a : list) {
			if (index == 0) {
				p(a);
			} else {
				p(" " + a);
			}
			index++;
		}
		pln();
	}

	class Point {
		int x;
		int y;
		int norm;

		public Point(int x, int y) {
			this.x = x;
			this.y = y;
			this.norm = x * x + y * y;
		}

		public int dist(Point other) {
			int dx = (x - other.x);
			int dy = (y - other.y);

			return dx * dx + dy * dy;
		}

		@Override
		public String toString() {
			return "Point [x=" + x + ", y=" + y + ", norm=" + norm + "]";
		}

	}

	BufferedReader in;
	PrintWriter out;
	StringTokenizer strTok = new StringTokenizer("");

	String nextToken() throws IOException {
		while (!strTok.hasMoreTokens())
			strTok = new StringTokenizer(in.readLine());
		return strTok.nextToken();
	}

	int ni() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nl() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nd() throws IOException {
		return Double.parseDouble(nextToken());
	}

	int[] nia(int size) throws IOException {
		int[] ret = new int[size];
		for (int i = 0; i < size; i++)
			ret[i] = ni();
		return ret;
	}

	long[] nla(int size) throws IOException {
		long[] ret = new long[size];
		for (int i = 0; i < size; i++)
			ret[i] = nl();
		return ret;
	}

	double[] nda(int size) throws IOException {
		double[] ret = new double[size];
		for (int i = 0; i < size; i++)
			ret[i] = nd();
		return ret;
	}

	String nextLine() throws IOException {
		strTok = new StringTokenizer("");
		return in.readLine();
	}

	boolean EOF() throws IOException {
		while (!strTok.hasMoreTokens()) {
			String s = in.readLine();
			if (s == null)
				return true;
			strTok = new StringTokenizer(s);
		}
		return false;
	}

	void printRepeat(String s, int count) {
		for (int i = 0; i < count; i++)
			out.print(s);
	}

	void printArray(int[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i > 0)
				out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(long[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i > 0)
				out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i > 0)
				out.print(' ');
			out.print(array[i]);
		}
		out.println();
	}

	void printArray(double[] array, String spec) {
		for (int i = 0; i < array.length; i++) {
			if (i > 0)
				out.print(' ');
			out.printf(Locale.US, spec, array[i]);
		}
		out.println();
	}

	void printArray(Object[] array) {
		boolean blank = false;
		for (Object x : array) {
			if (blank)
				out.print(' ');
			else
				blank = true;
			out.print(x);
		}
		out.println();
	}

	@SuppressWarnings("rawtypes")
	void printCollection(Collection collection) {
		boolean blank = false;
		for (Object x : collection) {
			if (blank)
				out.print(' ');
			else
				blank = true;
			out.print(x);
		}
		out.println();
	}

	static String memoryStatus() {
		return (Runtime.getRuntime().totalMemory()
				- Runtime.getRuntime().freeMemory() >> 20)
				+ "/" + (Runtime.getRuntime().totalMemory() >> 20) + " MB";
	}

	public void pln() {
		out.println();
	}

	public void pln(int arg) {
		out.println(arg);
	}

	public void pln(long arg) {
		out.println(arg);
	}

	public void pln(double arg) {
		out.println(arg);
	}

	public void pln(String arg) {
		out.println(arg);
	}

	public void pln(boolean arg) {
		out.println(arg);
	}

	public void pln(char arg) {
		out.println(arg);
	}

	public void pln(float arg) {
		out.println(arg);
	}

	public void pln(Object arg) {
		out.println(arg);
	}

	public void p(int arg) {
		out.print(arg);
	}

	public void p(long arg) {
		out.print(arg);
	}

	public void p(double arg) {
		out.print(arg);
	}

	public void p(String arg) {
		out.print(arg);
	}

	public void p(boolean arg) {
		out.print(arg);
	}

	public void p(char arg) {
		out.print(arg);
	}

	public void p(float arg) {
		out.print(arg);
	}

	public void p(Object arg) {
		out.print(arg);
	}

}


import java.util.Scanner;
import java.io.PrintWriter;
import java.util.*;

public class Order8C implements Runnable {
    private Scanner in = new Scanner(System.in);
    private PrintWriter out = new PrintWriter(System.out);

    int mintime;
    String path;

    int xs;
    int ys;
    int n;
    int[] obx;
    int[] oby;

    public static void main(String[] args) {
	new Thread(new Order8C()).start();
    }

    private void read() {
	xs = in.nextInt();
	ys = in.nextInt();
	n = in.nextInt();
	obx = new int[n];
	oby = new int[n];
	for(int i = 0; i<n; i++){
	    obx[i] = in.nextInt();
	    oby[i] = in.nextInt();
	}

    }

    private void solve() {
	/* we will do dynamic programming over the subsets
	   best[m] will be the shortest for binary digits of m
	   being in.
	   last[m] will be the last subset before m */

	int[] ds = new int[n];
	int[][] d = new int[n][n];

	int[] best = new int[1 << n];
	int[] last = new int[1 << n];

	for(int i = 0; i<n; i++){
	    ds[i] = (obx[i]-xs)*(obx[i]-xs) + (oby[i]-ys)*(oby[i]-ys);
	    for(int j = i+1; j<n; j++){
		d[i][j] = (obx[i]-obx[j])*(obx[i]-obx[j]) + (oby[i]-oby[j])*(oby[i]-oby[j]);
		d[j][i] = (obx[i]-obx[j])*(obx[i]-obx[j]) + (oby[i]-oby[j])*(oby[i]-oby[j]);
	    }
	}

	for(int i=0; i< (1<<n); i++){ //goes through subsets before supersets
	    best[i] = 100000000;
	}
	best[0] = 0;

	for(int i=0; i< (1<<n); i++){ //goes through subsets before supersets
	    /*if (i % 1000000 == 0 ){
		System.out.println(i);
		}*/
	    for(int j = 0; j<n; j++){
		if( ((1 << j) & i) != 0){ // if 2^j and i have bitwise sum nonzero
		    if(best[i - (1<<j)] + 2*ds[j] < best[i]){
			best[i] = best[i - (1<<j)] + 2*ds[j];
			last[i] = i - (1<< j);

		    }
		   for(int k = j+1; k<n; k++){
		       if( ((1 << k) & i) != 0){ // if 2^k and i have bitwise sum nonzero
			   if( (best[i-(1<<j) -(1<<k)] +ds[j]+ds[k]+d[j][k]) < best[i]){
			       best[i] = (best[i-(1<<j) -(1<<k)] +ds[j]+ds[k]+d[j][k]);
			       last[i] = i -(1<<j) - (1<< k);

			   }

		       }
		   }
		   break; // break here because order doesn't really matter, just knowing which pairs to roup
		}
	    }
	}
	int i = (1<<n) -1;
	mintime = best[i];
	path = "";

	while(i >0){
	    //System.out.println("Got to i = " + i + " and path is: " + path);
	    path = path + "0 ";
	    int dif = i-last[i]; // this has one or two 1s in binary
	    for(int j=0; j<n; j++){
		if( ((1<<j) & dif) != 0){ // if dif has a 1 in the j'th digit
		    path  = path + (j+1) + " ";
		}
	    }

	    i = last[i];
	}
	path = path + "0";
    }

    private void write() {
	out.println(mintime);
	out.println(path);
    }
    public void run() {
	read();
	solve();
	write();
	out.close();
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        int[] best = new int[1 << n];
        int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            best[set] = best[set ^ (1 << i)] + single[i];
            prev[set] = i + 1;
            for (int j = i + 1; j < n; ++j)
                if ((set & (1 << j)) != 0) {
                    int cur = best[set ^ (1 << i) ^ (1 << j)] + pair[i][j];
                    if (cur < best[set]) {
                        best[set] = cur;
                        prev[set] = (i + 1) * 100 + (j + 1);
                    }
                }
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
            int what = prev[now];
            int wa = what % 100 - 1;
            int wb = what / 100 - 1;
            if (wa >= 0) {
                writer.print(" ");
                writer.print(wa + 1);
                now ^= 1 << wa;
            }
            if (wb >= 0) {
                writer.print(" ");
                writer.print(wb + 1);
                now ^= 1 << wb;
            }
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

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


import java.util.Arrays;
import java.util.Scanner;

/**
 * @author vstepanov on 3/29/2017.
 */
public class Main {
    public static void main(String[] args) {
        try(Scanner in = new Scanner(System.in)) {
            int bx = in.nextInt();
            int by = in.nextInt();
            int n = in.nextInt();
            int[][] xy = new int[n][2];
            int[] res = new int[1 << n];
            int[] last = new int[1 << n];
            for (int i = 0; i < n; i++) {
                xy[i] = new int[]{in.nextInt(), in.nextInt()};
            }
            int[] ds = new int[n];
            for (int i = 0; i < ds.length; i++) {
                ds[i] = time(xy[i][0], xy[i][1], bx, by);
            }
            int[][] d = new int[n][n];
            for (int i = 0; i < d.length; i++) {
                for (int j = 0; j < d.length; j++) {
                    d[i][j] = time(xy[i][0], xy[i][1], xy[j][0], xy[j][1]);
                }
            }
            Arrays.fill(res, Integer.MAX_VALUE);
            res[0] = 0;
            for (int i = 0; i < (1 << n); i++) {
                for (int j = 0; j < n; j++) {
                    if ((i & mask(j)) != 0) {
                        if (res[i - mask(j)] + 2*ds[j] < res[i]) {
                            res[i] = res[i - mask(j)] + 2*ds[j];
                            last[i] = i - mask(j);
                        }
                        for (int k = j + 1; k < n; k++) {
                            if ((i & mask(k)) != 0) {
                                if (res[i - mask(k) - mask(j)] + ds[j] + ds[k] + d[j][k] < res[i]) {
                                    res[i] = res[i - mask(k) - mask(j)] + ds[j] + ds[k] + d[j][k];
                                    last[i] = i - mask(j) - mask(k);
                                }
                            }
                        }
                        break;
                    }
                }
            }

            int cur = (1 << n) - 1;
            System.out.println(res[cur]);
            int k = cur;
            while (k != 0) {
                System.out.print("0 ");
                int diff = k - last[k];
                for (int i = 0; i < n && diff != 0; i++) {
                    if (((diff >> i) & 1) != 0) {
                        System.out.print((i + 1) + " ");
                        diff -= (1 << i);
                    }
                }
                k = last[k];
            }
            System.out.println("0");
        }
    }

    static int mask(int i) {
        return 1 << i;
    }

    static int time(int x, int y, int x1, int y1) {
        return (x - x1)*(x - x1) + (y - y1)*(y - y1);
    }
}


import java.util.Arrays;
import java.util.Scanner;

public class C
{

    public static void main(String[] args)
    {
        new C();
    }

    final int oo = (int)1e9;

    int Hx,Hy;

    int N;
    int[][] P;

    int[] memo;
    int[][] soln;

    int[] dist1;
    int[][] dist2;

    C()
    {
        Scanner in = new Scanner(System.in);
        Hx=in.nextInt();
        Hy=in.nextInt();

        N=in.nextInt();
        P=new int[N][2];
        for (int i=0; i<N; ++i)
        {
            P[i][0]=in.nextInt();
            P[i][1]=in.nextInt();
        }

        memo=new int[1<<N];
        Arrays.fill(memo, -1);
        soln=new int[2][1<<N];

        dist1=new int[N];
        Arrays.fill(dist1, -1);
        dist2=new int[N][N];
        for (int[] d : dist2) Arrays.fill(d, -1);

        int res=go((1<<N)-1);
        System.out.println(res);

        int set=(1<<N)-1;
        while (set>0)
        {
            System.out.print("0 ");
            System.out.print((soln[0][set]+1)+" ");
            if (soln[1][set]>-1) System.out.print((soln[1][set]+1)+" ");

            if (soln[1][set]>-1)
            {
                set-=((1<<soln[0][set])+(1<<soln[1][set]));
            }
            else
            {
                set-=(1<<soln[0][set]);
            }
        }
        System.out.println("0");
    }

    int go(int set)
    {
        if (set==0)
            return 0;
        if (memo[set]>-1)
            return memo[set];

        int res=oo;
        int i=0;
        while (!on(set,i)) ++i;

        res=dist(i)+go(set-(1<<i));
        soln[0][set]=i;
        soln[1][set]=-1;

        for (int j=i+1; j<N; ++j)
        {
            if (on(set,j))
            {
                int tmp=dist(i,j)+go(set-(1<<i)-(1<<j));
                if (tmp<res)
                {
                    res=tmp;
                    soln[0][set]=i;
                    soln[1][set]=j;
                }
            }
        }

        return memo[set]=res;
    }

    // H->i->H
    int dist(int i)
    {
        if (dist1[i]>-1) return dist1[i];

        int dx=P[i][0]-Hx;
        int dy=P[i][1]-Hy;
        return dist1[i]=2*(dx*dx+dy*dy);
    }

    // H->i->j->H
    int dist(int i, int j)
    {
        if (dist2[i][j]>-1) return dist2[i][j];

        int res=0,dx,dy;

        dx=P[i][0]-Hx;
        dy=P[i][1]-Hy;
        res+=dx*dx+dy*dy;

        dx=P[i][0]-P[j][0];
        dy=P[i][1]-P[j][1];
        res+=dx*dx+dy*dy;

        dx=P[j][0]-Hx;
        dy=P[j][1]-Hy;
        res+=dx*dx+dy*dy;

        return dist2[i][j]=res;
    }

    boolean on(int set, int loc)
    {
        return (set&(1<<loc))>0;
    }
}


import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main implements Runnable {

    // ////////////////////////////////////////////////////////////////////
    // Solution

    private int n;
    private int nn;
    private int[][] D;
    private int[] dp;
    private int[] prev;

    private void solve() throws Throwable {
        int xs = nextInt(), ys = nextInt();
        n = nextInt();
        int[][] pts = new int[n][2];
        for (int i = 0; i < n; i++) {
            pts[i][0] = nextInt();
            pts[i][1] = nextInt();
        }
        D = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    D[i][i] = 2 * (sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys));
                } else {
                    D[i][j] = sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys)
                            + sqr(pts[i][0] - pts[j][0])
                            + sqr(pts[i][1] - pts[j][1]) + sqr(pts[j][0] - xs)
                            + sqr(pts[j][1] - ys);
                }
            }
        }
        nn = 1 << n;
        dp = new int[nn];
        prev = new int[nn];
        Arrays.fill(dp, -1);
        Arrays.fill(prev, -1);
        dp[0] = 0;
        Dp(nn - 1);
        pw.println(dp[nn - 1]);
        pw.print(0);
        for (int p = nn - 1; p != -1 && prev[p] != -1; p = prev[p]) {
            int vv = p ^ prev[p];
            for (int j = 0; j < n; j++) {
                int jj = 1 << j;
                if ((vv & jj) == 0) continue;
                pw.print(' ');
                pw.print(j + 1);
            }
            pw.print(" 0");
        }
        pw.println();
    }

    private int Dp(int i) {
        if (dp[i] != -1) return dp[i];
        int ans = 107374182, p = -1;
        int j1 = 1, pos1 = 0;
        for (; pos1 < n && j1 < nn; j1 *= 2, pos1++) {
            if ((i & j1) == 0) continue;
            int a = D[pos1][pos1] + Dp(i ^ j1);
            if (a < ans) {
                ans = a;
                p = i ^ j1;
            }
            int j2 = j1 * 2, pos2 = pos1 + 1;
            for (; pos2 < n && j2 < nn; j2 *= 2, pos2++) {
                if ((i & j2) == 0) continue;
                a = D[pos1][pos2] + Dp(i ^ (j1 | j2));
                if (a < ans) {
                    ans = a;
                    p = i ^ (j1 | j2);
                }
            }
            break;
        }
        dp[i] = ans;
        prev[i] = p;
        return ans;
    }

    private int sqr(int i) {
        return i * i;
    }

    // ////////////////////////////////////////////////////////////////////
    // Utility functions

    PrintWriter pw;
    BufferedReader in;
    StringTokenizer st;

    void initStreams() throws FileNotFoundException {
        //System.setIn(new FileInputStream("1"));
        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(System.out);
    }

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

    int nextInt() throws NumberFormatException, IOException {
        return Integer.parseInt(nextString());
    }

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

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

    static Throwable sError;

    public static void main(String[] args) throws Throwable {
//      Thread t = new Thread(null, new Main(), "1", 1 << 27);
//      t.start();
//      t.join();
        new Main().run();
        if (sError instanceof OutOfMemoryError) {
            throw sError;
        }
//      if (sError != null) {
//          throw sError;
//      }
    }

    public void run() {
        try {
            initStreams();
            solve();
        } catch (Throwable e) {
            sError = e;
        } finally {
            if (pw != null)
                pw.close();
        }
    }
}


import java.util.*;
public class c8 {
    static int n;
    static int[] ds;
    static int[][] g;
public static void main(String[] args)
{
    Scanner input = new Scanner(System.in);
    int x = input.nextInt(), y = input.nextInt();
    int n = input.nextInt();
    int[] xs = new int[n], ys = new int[n];
    for(int i = 0; i<n; i++)
    {
        xs[i] = input.nextInt();
        ys[i] = input.nextInt();
    }
    ds = new int[n];
    g = new int[n][n];
    for(int i = 0; i<n; i++)
    {
        ds[i] = (x - xs[i])  *  (x - xs[i]) + (y - ys[i]) * (y - ys[i]);
        for(int j = 0; j<n; j++)
        {
            g[i][j] = (xs[i] - xs[j]) * (xs[i] - xs[j]) + (ys[i] - ys[j]) * (ys[i] - ys[j]);
        }
    }
    int[] dp = new int[1<<n];
    Arrays.fill(dp, 987654321);
    dp[0] = 0;
    for(int i = 0; i<(1<<n); i++)
    {
        if(dp[i] == 987654321) continue;
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) > 0) continue;
            dp[i | (1<<a)] = Math.min(dp[i | (1<<a)], dp[i] + 2*ds[a]);
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) > 0) continue;
                dp[i | (1<<a) | (1<<b)] = Math.min(dp[i | (1<<a) | (1<<b)], dp[i] + ds[a] + ds[b] + g[a][b]);
            }
            break;
        }
    }
    Stack<Integer> stk = new Stack<Integer>();
    stk.add(0);
    int i = (1<<n) - 1;
    //System.out.println(Arrays.toString(dp));

    trace:
    while(i > 0)
    {
        //System.out.println(i);
        for(int a = 0; a<n; a++)
        {
            if((i & (1<<a)) == 0) continue;
            if( dp[i] == dp[i - (1<<a)] + 2*ds[a])
            {
                stk.add(a+1);
                stk.add(0);
                i -= (1<<a);
                continue trace;
            }
            for(int b = a+1; b<n; b++)
            {
                if((i & (1<<b)) == 0) continue;
                if(dp[i] == dp[i - (1<<a) - (1<<b)] + ds[a] + ds[b] + g[a][b])
                {
                    stk.add(a+1);
                    stk.add(b+1);
                    stk.add(0);
                    i -= (1<<a) + (1<<b);
                    continue trace;
                }
            }
            //break;
        }
    }
    System.out.println(dp[(1<<n) - 1]);
    while(!stk.isEmpty()) System.out.print(stk.pop()+" ");
}
}


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

public class A558 {
  static BufferedReader in = null;
  static PrintWriter out = null;
  static StringTokenizer st = new StringTokenizer("");

  public static void main(String[] args) {
    try {
      in = new BufferedReader(new InputStreamReader(System.in));
      out = new PrintWriter(System.out);
      solve();
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public static String readString() {
    while (!st.hasMoreTokens()) {
      try {
        st = new StringTokenizer(in.readLine(), " \n\r\t:");
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return st.nextToken();
  }

  public static int readInt() {
    return Integer.parseInt(readString());
  }

  public static long readLong() {
    return Long.parseLong(readString());
  }

  private static int MAX_VALUE = Integer.MAX_VALUE - 10000000;
  private static int[] dp;
  private static int[] parents;
  private static int[] powers;
  private static int[] x;
  private static int[] y;
  private static int[][] dist;
  private static int[] distFrom0;

  private static void solve() throws IOException {
    int x0 = readInt();
    int y0 = readInt();
    int n = readInt();
    long time = System.currentTimeMillis();
    x = new int[n];
    y = new int[n];
    for (int i = 0; i < n; i++) {
      x[i] = readInt() - x0;
      y[i] = readInt() - y0;
    }
    dist = new int[n][n];
    distFrom0 = new int[n];
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        dist[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
      }
    }
    for (int i = 0; i < n; i++) {
      distFrom0[i] = x[i] * x[i] + y[i] * y[i];
    }
    powers = new int[n + 1];
    powers[0] = 1;
    for (int i = 1; i < n + 1; i++) {
      powers[i] = powers[i - 1] * 2;
    }
    int maxMask = 1 << n;
    dp = new int[maxMask];
    parents = new int[maxMask];
    Arrays.fill(dp, MAX_VALUE);
    dp[0] = 0;
    for (int i = 0; i < maxMask; i++) {
      if (dp[i] != MAX_VALUE) {
        int curMask = i;
        int notUsed = 0;
        for (int j = 0; j < n; j++) {
          if ((curMask & powers[j]) == 0) {
            notUsed = j;
            break;
          }
        }
        int mask = curMask | powers[notUsed];
        for (int j = notUsed; j < n; j++) {
          if ((powers[j] & curMask) == 0 || j == notUsed) {
            int nextMask = mask | powers[j];
            int minDist = dp[curMask] + distFrom0[notUsed] + dist[notUsed][j] + distFrom0[j];
            if (dp[nextMask] > minDist) {
              dp[nextMask] = minDist;
              parents[nextMask] = curMask;
            }
          }
        }
      }
    }
   // System.err.println(((System.currentTimeMillis() - time)));
    // brute(n, 0)
    maxMask--;
    out.println(dp[maxMask]);
    while (maxMask != 0) {
      out.print("0 ");
      int[] diffBits = getBits(n, maxMask, parents[maxMask]);
      for (int i = 1; i <= diffBits[0]; i++) {
        out.print(diffBits[i] + 1 + " ");
      }
      maxMask = parents[maxMask];
    }
    out.print(0);
    //System.err.println((System.currentTimeMillis() - time));
  }

  private static boolean hasBit(int x, int index) {
    return (powers[index] & x) != 0;
  }

  private static int setBit(int x, int index) {
    return (x | powers[index]);
  }

  private static int getDist(int xFrom, int yFrom, int xTo, int yTo) {
    return (xTo - xFrom) * (xTo - xFrom) + (yTo - yFrom) * (yTo - yFrom);
  }

  private static int[] getBits(int n, int nextMask, int curMask) {
    int[] res = new int[3];
    for (int i = 0; i < n; i++) {
      if (hasBit(nextMask, i) ^ hasBit(curMask, i)) {
        res[++res[0]] = i;
      }
    }
    return res;
  }

  private static void brute(int n, int mask) {
    List<Integer> listNotTaken = new ArrayList<>();
    for (int i = 0; i < n; i++) {
      if (!hasBit(mask, i)) {
        listNotTaken.add(i);
      }
    }
    for (int first : listNotTaken) {
      int temp = setBit(mask, first);
      for (int second : listNotTaken) {
        int nextMask = setBit(temp, second);
        int minDist = dp[mask] + getDist(0, 0, x[first], y[first]) + getDist(x[first], y[first], x[second], y[second]) + getDist(x[second], y[second], 0, 0);
        if (dp[nextMask] > minDist) {
          dp[nextMask] = minDist;
          parents[nextMask] = mask;
          brute(n, nextMask);
        }
      }
    }
  }

}


import java.awt.Point;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

	static int n, memo[], dS[], dd[][];

	static int dp(int idx, int msk)
	{
		if(msk == (1 << n) - 1)
			return 0;
		if(memo[msk] != -1)
			return memo[msk];
		while((msk & 1 << idx) != 0)
			++idx;
		int ret = dS[idx] * 2 + dp(idx + 1, msk | 1 << idx);
		for(int i = 0; i < n; ++i)
			if((msk & 1 << i) == 0)
				ret = Math.min(ret, dS[i] + dS[idx] + dd[i][idx] + dp(idx + 1, msk | 1 << i | 1 << idx));
		return memo[msk] = ret;
	}

	static StringBuilder sb = new StringBuilder("0 ");

	static void print(int idx, int msk)
	{
		if(msk == (1 << n) - 1)
			return;
		int opt = dp(idx, msk);
		while((msk & 1 << idx) != 0)
			++idx;
		if(dS[idx] * 2 + dp(idx + 1, msk | 1 << idx) == opt)
		{
			sb.append((idx + 1) + " 0 ");
			print(idx + 1, msk | 1 << idx);
			return;
		}
		for(int i = 0; i < n; ++i)
			if((msk & 1 << i) == 0)
				if(opt == dS[i] + dS[idx] + dd[i][idx] + dp(idx + 1, msk | 1 << i | 1 << idx))
				{
					sb.append((idx + 1) + " " + (i + 1) + " 0 ");
					print(idx + 1, msk | 1 << i | 1 << idx);
					return;
				}
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		Point s = new Point(sc.nextInt(), sc.nextInt());
		n = sc.nextInt();
		Point[] a = new Point[n];
		for(int i = 0; i < n; ++i)
			a[i] = new Point(sc.nextInt(), sc.nextInt());
		dS = new int[n];
		dd = new int[n][n];
		for(int i = 0; i < n; ++i)
		{
			dS[i] = dist2(s, a[i]);
			for(int j = 0; j < n; ++j)
				dd[i][j] = dist2(a[i], a[j]);
		}

		memo = new int[1 << n];
		Arrays.fill(memo, -1);
		out.println(dp(0, 0));
		print(0, 0);
		out.println(sb);
		out.flush();
		out.close();
	}

	static int dist2(Point a, Point b) { return sq(a.x - b.x) + sq(a.y - b.y); }

	static int sq(int x) { return x * x; }

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

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

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

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

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

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

		public boolean ready() throws IOException {return br.ready();}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main implements Runnable {

    // ////////////////////////////////////////////////////
    // Solution

    private int n;
    private int nn;
    private int[][] D;
    private int[] dp;
    private int[] prev;

    private void solve() throws Throwable {
        int xs = nextInt(), ys = nextInt();
        n = nextInt();
        int[][] pts = new int[n][2];
        for (int i = 0; i < n; i++) {
            pts[i][0] = nextInt();
            pts[i][1] = nextInt();
        }
        D = new int[n][n];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    D[i][i] = 2 * (sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys));
                } else {
                    D[i][j] = sqr(pts[i][0] - xs) + sqr(pts[i][1] - ys)
                            + sqr(pts[i][0] - pts[j][0])
                            + sqr(pts[i][1] - pts[j][1]) + sqr(pts[j][0] - xs)
                            + sqr(pts[j][1] - ys);
                }
            }
        }
        nn = 1 << n;
        dp = new int[nn];
        prev = new int[nn];
        Arrays.fill(dp, -1);
        Arrays.fill(prev, -1);
        dp[0] = 0;
        Dp(nn - 1);
        pw.println(dp[nn - 1]);
        pw.print(0);
        for (int p = nn - 1; p != -1 && prev[p] != -1; p = prev[p]) {
            int vv = p ^ prev[p];
            for (int j = 0; j < n; j++) {
                int jj = 1 << j;
                if ((vv & jj) == 0)
                    continue;
                pw.print(' ');
                pw.print(j + 1);
            }
            pw.print(" 0");
        }
        pw.println();
    }

    private int Dp(int i) {
        if (dp[i] != -1)
            return dp[i];
        int ans = 107374182, p = -1;
        int j1 = 1, pos1 = 0;
        for (; pos1 < n && j1 < nn; j1 *= 2, pos1++) {
            if ((i & j1) == 0)
                continue;
            int a = D[pos1][pos1] + Dp(i ^ j1);
            if (a < ans) {
                ans = a;
                p = i ^ j1;
            }
            int j2 = j1 * 2, pos2 = pos1 + 1;
            for (; pos2 < n && j2 < nn; j2 *= 2, pos2++) {
                if ((i & j2) == 0)
                    continue;
                a = D[pos1][pos2] + Dp(i ^ (j1 | j2));
                if (a < ans) {
                    ans = a;
                    p = i ^ (j1 | j2);
                }
            }
            break;
        }
        dp[i] = ans;
        prev[i] = p;
        return ans;
    }

    private int sqr(int i) {
        return i * i;
    }

    // ////////////////////////////////////////////////////
    // Utility functions

    private void initstreams() throws Throwable {
        //System.setIn(new FileInputStream("1"));
        in = new BufferedReader(new InputStreamReader(System.in, "ISO-8859-1"));
        pw = new PrintWriter(System.out);
    }

    BufferedReader in;
    PrintWriter pw;
    StringTokenizer st;

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

    int nextInt() throws NumberFormatException, IOException {
        return Integer.parseInt(nextString());
    }

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

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

    @Override
    public void run() {
        try {
            initstreams();
            solve();
        } catch (Throwable e) {
            sError = e;
        } finally {
            if (pw != null)
                pw.close();
        }
    }

    private static Throwable sError;

    public static void main(String[] args) throws Throwable {
        Thread t = new Thread(new Main());
        t.start();
        t.join();
        if (sError != null)
            throw sError;
    }
}


import java.util.*;

public class C
{
   public static void main(String[] args)
   {
      new C(new Scanner(System.in));
   }

   vect[] vs;
   int N;
   int oo = 987654321;

   ArrayList<choice> cs;
   choice[][] cg;

   int MF;

   int[] memo;
   int[] next;

   int go(int m)
   {
      if (m == MF)
         return 0;
      if (memo[m] != -1)
         return memo[m];

      // Try a new place
      int res = oo;
      int nxt = -1;

      int i=0;
      for (i=0; i<N; i++)
      {
         if (((1<<i)&m) == 0)
            break;
      }

      for (int j=0; j<N; j++)
      {
         choice cc = cg[i][j];
         if ((m&cc.m) > 0)
            continue;

         int r2 = cc.cost+go(m|cc.m);
         if (r2 < res)
         {
            res = r2;
            nxt = cc.index;
         }
      }

      memo[m] = res;
      next[m] = nxt;
      return res;
   }

   public C(Scanner in)
   {
      vect vt = new vect(in.nextInt(), in.nextInt());
      N = in.nextInt();
      vs = new vect[N+1];
      vs[N] = vt;
      for (int i=0; i<N; i++)
         vs[i] = new vect(in.nextInt(), in.nextInt());

      // Precompute all choices and masks
      cs = new ArrayList<choice>();
      cg = new choice[N][N];
      for (int i=0; i<N; i++)
      {
         choice cc = new choice(cs.size(), 2*vs[i].dist(vt), 1<<i);
         cc.add(i);
         cs.add(cc);
         cg[i][i] = cc;
      }

      for (int i=0; i<N; i++)
      {
         for (int j=i+1; j<N; j++)
         {
            int dist = vs[i].dist(vt);
            dist += vs[i].dist(vs[j]);
            dist += vs[j].dist(vt);
            choice cc = new choice(cs.size(), dist, (1<<i)|(1<<j));
            cc.add(i); cc.add(j);
            cs.add(cc);
            cg[i][j] = cc;
            cg[j][i] = cc;
         }
      }

      MF = (1<<N)-1;
      next = new int[MF+1];
      memo = new int[MF+1];

      Arrays.fill(next, -1);
      Arrays.fill(memo, -1);

      int res = go(0);
      System.out.println(res);

      int m = 0;
      StringBuilder sb = new StringBuilder();
      while (m != -1)
      {
         //System.out.println(Integer.toBinaryString(m));
         sb.append(0);
         sb.append(' ');
         int i = next[m];
         if (i == -1)
            break;
         choice cc = cs.get(i);
         for (int j : cc.iv)
         {
            sb.append(f(j));
            sb.append(' ');
         }
         m = m|cc.m;
      }
      System.out.println(sb.toString().trim());
   }

   int f(int i)
   {
      if (i == N)
         return 0;
      return i+1;
   }
}

class choice
{
   int cost;
   int m;
   int index;
   ArrayList<Integer> iv;

   public choice(int ii, int c, int mm)
   {
      index = ii;
      cost = c;
      m = mm;
      iv = new ArrayList<Integer>(2);
   }

   void add(int i)
   {
      iv.add(i);
   }
}

class vect
{
   int x, y;

   public vect(int i, int j)
   {
      x=i; y=j;
   }

   int dist(vect rhs)
   {
      int xx = x-rhs.x;
      int yy = y-rhs.y;
      return xx*xx+yy*yy;
   }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 * Created by Brandt Henslee on 2/24/2015.
 */
public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        String[] parsedString;
        int objectNum = 0;
        int xStart=0;
        int yStart=0;

        parsedString = in.readLine().split(" ");
        xStart = Integer.parseInt(parsedString[0]);
        yStart = Integer.parseInt(parsedString[1]);
        objectNum = Integer.parseInt(in.readLine());

        int[] xLocs = new int[objectNum+1];
        int[] yLocs = new int[objectNum+1];
        int[] bitMasks = new int[1<<objectNum];
        Arrays.fill(bitMasks, -1);
        int[] previous = new int[1<<objectNum];

        xLocs[objectNum]=xStart;
        yLocs[objectNum]=yStart;
        for(int i=0; i<objectNum; i++){
            parsedString = in.readLine().split(" ");
            xLocs[i] = Integer.parseInt(parsedString[0]);
            yLocs[i] = Integer.parseInt(parsedString[1]);
        }

        //go through all pairs and find time requirement for each pair of objects
        //the entry at point [i][j] is equal to the time it takes to get from point i to point j
        int[][] times = new int[objectNum+1][objectNum+1];
        for(int i=0;i<=objectNum;i++){
            for(int j=0; j<=objectNum;j++){
                times[i][j] = times[j][i] = (xLocs[i]-xLocs[j])*(xLocs[i]-xLocs[j])+(yLocs[i]-yLocs[j])*(yLocs[i]-yLocs[j]);
            }
        }

        //each value in bitmasks represents the minimum time necessary to get
        //the unmasked bits
        //so bitmasks[5] (5=101) is the fastest time in which you can get
        //items 1 and 3
        bitMasks[0] = 0; //collecting zero objects takes 0 time
        //1<<n makes the n+1 position in the bit string = 1
        //1<<2 = 100
        for (int i=0; i<(1<<objectNum); i++){
            if(bitMasks[i]==-1) {

            }else{
                for(int j=0; j<objectNum; j++){
                    if(((1<<j)&i) == 0){ //if our current j object hasn't been picked up yet
                        int curState = (1<<j) | i; //ith state after picking up j object
                        int curTime = bitMasks[i] + 2*times[objectNum][j]; //time required to get object j from bag at state i

                        if(bitMasks[curState] == -1 || curTime < bitMasks[curState]){
                            bitMasks[curState] = curTime; //put fastest time in for gettingto our current state
                            previous[curState] = i;
                        }

                        for(int k=0; k<objectNum; k++){
                            if(((1<<k) & curState) == 0){ //if the kth position in our current state hasn't been picked up
                                int kState = ((1<<k) | curState); //curstate after picking pu kth object
                                //kTime is time it takes to go from bag, to j, to k and back
                                int kTime = bitMasks[i] + times[objectNum][j] + times[j][k] + times[k][objectNum];

                                if(bitMasks[kState] == -1 || kTime < bitMasks[kState]){
                                    bitMasks[kState] = kTime;  //put shortest tiem in for getting to kState
                                    previous[kState] = i;
                                }
                            }
                        }
                        break;
                    }
                }
            }

        }

        int finalState = (1<<objectNum)-1;

        System.out.println(bitMasks[finalState]);

        Deque<Integer> outputQ = new ArrayDeque<Integer>();
        outputQ.add(0);
        int curState = finalState;
        while(curState>0){
            //1100 ^ 1101 = 0001
            //difference is the objects picked up in this state but not in previous state
            int difference = curState ^ previous[curState];
            int firstItem = -1;
            int secondItem = -1;

            for(int i=0; i<objectNum; i++){
                if(((1<<i)&difference)>0){ //if the ith object was picked up in this state
                    secondItem=firstItem; //keep track of how many items are picked up
                    firstItem=i;
                }
            }

            if(secondItem!=-1){
                //put in two items followed by a return to 0

                outputQ.add(firstItem+1);
                outputQ.add(secondItem+1);
                outputQ.add(0);
            }
            else{
                outputQ.add(firstItem + 1);
                outputQ.add(0);
            }

            curState = previous[curState];
        }

        System.out.print(outputQ.removeLast());
        while(!outputQ.isEmpty()){
            System.out.print(" ");
            System.out.print(outputQ.removeLast());
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;

public class Handbag
{
	// http://codeforces.com/problemset/problem/8/C
	// Source of most code : http://codeforces.com/contest/8/submission/3492661

	// Keep track of each item location and also be able to
	// calculate distance between it and another object
	public static class Item{
		int x;
		int y;

		Item(int x, int y){
			this.x = x;
			this.y = y;
		}

		// Return distance between two points
		public int dist(Item i){
			int dx = x - i.x;
			int dy = y - i.y;
			return dx*dx + dy*dy;
		}
	}

	// Each value in bits[] is the min time to get certain objects
    // Ex. bits[6] = 110 is the fastest time to get items that correspond with the '1s'
	public static int solve(int bitNum){

		if(bitNum == (1 << N) - 1) // If bitNum is too big for the array
			return 0;

		if(bits[bitNum] != -1) // If bit value has already been calculated
			return bits[bitNum];

		int ans = Integer.MAX_VALUE;
		int j = 0;
		for(int i = 1; i < N; i++){

			if((bitNum & (1 << i)) == 0){ // Performs bitwise AND operation to see if bitNum and i have no bits in common

				if(j == 0){ // Only happens on the first time in IF statement
					// One item that can be picked up before returning to handbag
					ans = 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i)); // Performs bitwise exclusive OR operation
					j = i; // Change value so this case isn't ever hit again && to store value to use in else statement dists
				}
				else{
					// Find the distance between the handbag and the first item
					int dist1 = items[0].dist(items[i]);
					// Find the distance between the first item and the second item
					int dist2 = items[i].dist(items[j]);
					// Find the distance between the second item and the handbag
					int dist3 = items[j].dist(items[0]);

					// Two items that can be picked up before returning to handbag
					// distance covered between any two objects in the time equal
					// to the squared length of the segment between the points of the objects
					ans = Math.min(ans, dist1 + dist2 + dist3 + solve(bitNum | (1 << i) | (1 << j))); // Performs bitwise exclusive OR operation
				}
			}
		}
		return bits[bitNum] = ans; // Store all values in bits[] to speed up solve and for use in printOptPath
	}

	static void printOptPath(int bitNum) {
		if (bitNum == (1 << N) - 1)
			return;

		// Almost identical to solve equation except it doesn't calculate the answer, it checks the stored answer in bits
		int j = 0;
		for (int i = 1; i < N; i++)

			if ((bitNum & (1 << i)) == 0) {
				if (j == 0) {
					j = i; // Change value so this case isn't ever hit again && to find distance to this specific item in else if statement
					if (bits[bitNum] == 2 * items[0].dist(items[i]) + solve(bitNum | (1 << i))) { // solve() should quickly return an answer because the bits[] has already been calculated
						pw.print(" " + i + " 0"); // One item that can be picked up before returning to handbag
						printOptPath(bitNum | (1 << i)); // Recursively call print with new bitNum
						return;
					}
				}
				else if (bits[bitNum] ==
								items[0].dist(items[i]) + items[i].dist(items[j]) + items[j].dist(items[0]) + solve(bitNum | (1 << i) | (1 << j))) {

					pw.print(" " + j + " " + i + " 0"); // Two items that can be picked up before returning to handbag
					printOptPath(bitNum | (1 << i) | (1 << j)); // Recursively call print with new bitNum
					return;
				}
			}
	}

	private static int N = 0;
	private static Item[] items;
	private static int[] bits;

	// PrintWriter needs to be class member because of recursive print strategy
	private static PrintWriter pw = new PrintWriter(System.out);

	public static void main(String[] args) throws IOException
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String[] input = br.readLine().split(" ");
		Item handbag = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));

		N = Integer.parseInt(br.readLine()) + 1;
		items = new Item[N];
		for(int n = 1; n < N; n++){
			input = br.readLine().split(" ");
			items[n] = new Item(Integer.parseInt(input[0]), Integer.parseInt(input[1]));
		}
		items[0] = handbag;

		// x << n is a right shift operator
		// which will remove the last n bits from x
		// Ex 1 << 2 => 4
		bits = new int[1 << N]; // Ex: 1 << 3 = 8; 1 << 5 = 64
		Arrays.fill(bits, -1); // Init bits array to hold -1 values

		int ans = solve(1 << 0); // Start solving with bit #1
		pw.println(ans); // Min time needed to put items in handbag

		pw.print("0"); // Init output with handbag location
		printOptPath(1 << 0); // Print possible optimum path to pick up items

		pw.close();
	}
}


//package round8;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;

public class C {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int x = ni(), y = ni();
		int n = ni();
		int[][] co = new int[n][];
		for(int i = 0;i < n;i++){
			co[i] = new int[]{ni()-x, ni()-y};
		}

		int[] c1 = new int[n];
		int[][] c2 = new int[n][n];
		for(int i = 0;i < n;i++){
			c1[i] = (co[i][0]*co[i][0]+co[i][1]*co[i][1])*2;
		}
		for(int i = 0;i < n;i++){
			for(int j = i+1;j < n;j++){
				c2[i][j] = c2[j][i] = (co[i][0]*co[i][0]+co[i][1]*co[i][1])+(co[j][0]*co[j][0]+co[j][1]*co[j][1])+(co[j][0]-co[i][0])*(co[j][0]-co[i][0])+(co[j][1]-co[i][1])*(co[j][1]-co[i][1]);
			}
		}

		int[] dp = new int[1<<n];
		int[] prev = new int[1<<n];
		prev[0] = -1;
		for(int i = 1;i < 1<<n;i++){
			int a = Integer.numberOfTrailingZeros(i);
			dp[i] = c1[a] + dp[i^1<<a];
			prev[i] = 1<<a;
			for(int j = a+1;j < n;j++){
				if(i<<31-j<0){
					int v = dp[i^1<<a^1<<j] + c2[a][j];
					if(v < dp[i]){
						dp[i] = v;
						prev[i] = 1<<a^1<<j;
					}
				}
			}
		}
		out.println(dp[(1<<n)-1]);
		int cur = (1<<n)-1;
		out.print("0");
		while(true){
			int targ;
			if(prev[cur] == -1){
				targ = cur;
			}else{
				targ = prev[cur];
				cur ^= prev[cur];
			}
			int a = Integer.numberOfTrailingZeros(targ);
			int b = Integer.numberOfTrailingZeros(targ&targ-1);
			if(targ == 1<<a){
				out.print(" " + (a+1));
			}else{
				out.print(" " + (a+1));
				out.print(" " + (b+1));
			}
			out.print(" 0");
			if(cur == 0)break;
		}
		out.println();
	}

	void run() throws Exception
	{
//		int n = 24, m = 99999;
//		Random gen = new Random();
//		StringBuilder sb = new StringBuilder();
//		sb.append(0 + " " + 0  + " " + n + " ");
//		for(int i = 0;i < n;i++){
//			sb.append(gen.nextInt(100) + " ");
//			sb.append(gen.nextInt(100) + " ");
//		}
//		INPUT = sb.toString();

		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new C().run();
	}

	public int ni()
	{
		try {
			int num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public long nl()
	{
		try {
			long num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public String ns()
	{
		try{
			int b = 0;
			StringBuilder sb = new StringBuilder();
			while((b = is.read()) != -1 && (b == '\r' || b == '\n' || b == ' '));
			if(b == -1)return "";
			sb.append((char)b);
			while(true){
				b = is.read();
				if(b == -1)return sb.toString();
				if(b == '\r' || b == '\n' || b == ' ')return sb.toString();
				sb.append((char)b);
			}
		} catch (IOException e) {
		}
		return "";
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		try{
			int b = 0, p = 0;
			while((b = is.read()) != -1 && (b == ' ' || b == '\r' || b == '\n'));
			if(b == -1)return null;
			buf[p++] = (char)b;
			while(p < n){
				b = is.read();
				if(b == -1 || b == ' ' || b == '\r' || b == '\n')break;
				buf[p++] = (char)b;
			}
			return Arrays.copyOf(buf, p);
		} catch (IOException e) {
		}
		return null;
	}

	double nd() { return Double.parseDouble(ns()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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

public class C {
	public static void main(String[] args) {
		new C().run();
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;
		boolean eof;
		String buf;

		public FastScanner(String fileName) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(fileName));
			nextToken();
		}

		public FastScanner(InputStream stream) {
			br = new BufferedReader(new InputStreamReader(stream));
			nextToken();
		}

		String nextToken() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					eof = true;
					break;
				}
			}
			String ret = buf;
			buf = eof ? "-1" : st.nextToken();
			return ret;
		}

		int nextInt() {
			return Integer.parseInt(nextToken());
		}

		long nextLong() {
			return Long.parseLong(nextToken());
		}

		double nextDouble() {
			return Double.parseDouble(nextToken());
		}

		void close() {
			try {
				br.close();
			} catch (Exception e) {

			}
		}

		boolean isEOF() {
			return eof;
		}
	}

	FastScanner sc;
	PrintWriter out;

	public void run() {
		Locale.setDefault(Locale.US);
		try {
			sc = new FastScanner(System.in);
			out = new PrintWriter(System.out);
			solve();
			sc.close();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	long nextLong() {
		return sc.nextLong();
	}

	double nextDouble() {
		return sc.nextDouble();
	}

	int nextInt() {
		return sc.nextInt();
	}

	String nextToken() {
		return sc.nextToken();
	}

	static class Point {
		int x, y;

		public Point(int x, int y) {
			super();
			this.x = x;
			this.y = y;
		}

		int dist(Point p) {
			return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y);
		}
	}

	void solve() {
		Point p0 = new Point(nextInt(), nextInt());
		int n = nextInt();
		Point[] p = new Point[n];
		for (int i = 0; i < n; i++) {
			p[i] = new Point(nextInt(), nextInt());
		}
		int[][] d = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				d[i][j] = p[i].dist(p[j]);
			}
		}
		int[] d0 = new int[n];
		for (int i = 0; i < n; i++) {
			d0[i] = p0.dist(p[i]);
		}
		int[] dp = new int[1 << n];
		Arrays.fill(dp, 1 << 30);
		dp[0] = 0;
		int[] from = new int[1 << n];
		for (int i = 0; i + 1 < 1 << n; i++) {
			int j = Integer.numberOfTrailingZeros(Integer.lowestOneBit(~i));
			int cnt = dp[i] + 2 * d0[j];
			if (dp[i ^ (1 << j)] > cnt) {
				dp[i ^ (1 << j)] = cnt;
				from[i ^ (1 << j)] = i;
			}
			for (int k = j + 1; k < n; k++) {
				if (((i >> k) & 1) == 0) {
					cnt = dp[i] + d0[j] + d0[k] + d[j][k];
					if (dp[i ^ (1 << j) ^ (1 << k)] > cnt) {
						dp[i ^ (1 << j) ^ (1 << k)] = cnt;
						from[i ^ (1 << j) ^ (1 << k)] = i;
					}
				}
			}
		}
		ArrayList<Integer> ans = new ArrayList<Integer>();
		ans.add(0);
		int mask = (1 << n) - 1;
		while (mask > 0) {
			int xor = mask ^ from[mask];
			while (xor > 0) {
				ans.add(Integer
						.numberOfTrailingZeros(Integer.lowestOneBit(xor)) + 1);
				xor = xor & (xor - 1);
			}
			ans.add(0);
			mask = from[mask];
		}
		out.println(dp[(1 << n) - 1]);
		for (int i : ans) {
			out.print(i + " ");
		}
	}
}


import java.io.*;
import static java.lang.Math.*;
import java.util.*;
import java.util.function.*;
import java.lang.*;

public class Main {
    final static boolean debug = false;
    final static String fileName = "";
    final static boolean useFiles = false;

    public static void main(String[] args) throws FileNotFoundException {
        long start;
        if (debug)
            start = System.nanoTime();
        InputStream inputStream;
        OutputStream outputStream;
        if (useFiles) {
            inputStream = new FileInputStream(fileName + ".in");
            outputStream = new FileOutputStream(fileName + ".out");
        } else {
            inputStream = System.in;
            outputStream = System.out;
        }
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Task solver = new Task(in, out);
        solver.solve();
        if(debug)
            out.println((System.nanoTime() - start) / 1e+9);
        out.close();
    }
}
class Task {
    int[][] dist, pre;
    int[] x, y, d, prev;
    String[] leafDescription;
    String[] linerDescription;
    String[][] allDescriptions;
    int xs, ys, n;

    int dist(int i, int j) {
        return (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
    }

    void go(int[] prev, String[] leafDescription, int[] d, int len, int add, String description){
        for (int mask = 0; mask < d.length; mask++) {
            if ((mask & add) != add)
                continue;
            int newValue = d[mask & (~add)] + len;
            if (d[mask] > newValue){
                d[mask] = newValue;
                leafDescription[mask] = description;
                prev[mask] = mask & (~add);
            }
        }
    }

    int rec(int mask) {
        if (d[mask] != -1)
            return d[mask];
        int lowest = 0;
        for (; ((1 << lowest) & mask) == 0; lowest++) ;

        int newMask = mask & (~(1 << lowest));
        d[mask] = rec(newMask) + dist[lowest][n];
        prev[mask] = newMask;
        leafDescription[mask] = linerDescription[lowest];

        for (int bit = lowest + 1; bit < n; bit++) {
            if (((1 << bit) & mask) > 0) {
                newMask = mask & (~(1 << bit)) & (~(1 << lowest));
                int newValue = rec(newMask) + pre[bit][lowest];
                if (newValue < d[mask]) {
                    d[mask] = newValue;
                    prev[mask] = newMask;
                    leafDescription[mask] = allDescriptions[lowest][bit];
                }
            }
        }
        return d[mask];
    }

    public void solve() {
        final int inf = (int) 1e+9;
        xs = in.nextInt();
        ys = in.nextInt();

        n = in.nextInt();
        x = new int[n + 1];
        y = new int[n + 1];
        for (int i = 0; i < n; i++) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        x[n] = xs;
        y[n] = ys;

        allDescriptions = new String[n][n];
        for (int i = 0; i < n; i++){
            for (int j = 0; j < n; j++){
                allDescriptions[i][j] = (i + 1) + " " + (j + 1) + " ";
            }
        }

        linerDescription = new String[n];
        for (int i = 0; i < n; i++){
            linerDescription[i] = (i + 1) + " ";
        }

        dist = new int[n + 1][n + 1];
        pre = new int[n + 1][n + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= n; j++) {
                dist[i][j] = 2 * dist(i, j);
                pre[i][j] = dist(i, n) + dist(i, j) + dist(j, n);
            }
        }

        d = new int[1 << n];
        Arrays.fill(d, -1);
        d[0] = 0;
        prev = new int[1 << n];
        leafDescription = new String[1 << n];
//        Arrays.fill(d, inf);
//        prev[0] = 0;
//        d[0] = 0;
//        for (int i = 0; i < n; i++) {
//            int add = 1 << i;
//            int len = 2 * dist[n][i];
//            String description = (i + 1) + " ";
//
//            go(prev, leafDescription, d, len, add, description);
//        }
//        for (int i = 0; i < n; i++) {
//            for (int j = i + 1; j < n; j++) {
//                int add = (1 << i) | (1 << j);
//                int len = dist[n][i] + dist[i][j] + dist[n][j];
//                String description = (i + 1) + " " + (j + 1) + " ";
//
//                go(prev, leafDescription, d, len, add, description);
//            }
//        }
//        Debug.printObjects(out, d);
//        Debug.printObjects(out, prev);
//        Debug.printObjects(out, leafDescription);
        int result = rec((1 << n) - 1);
        String answer = "";
        for (int curr = d.length - 1; prev[curr] != curr; curr = prev[curr] ){
            answer += "0 " + leafDescription[curr];
        }
        answer += "0";
        out.println(result);
        out.println(answer);
    }

    private InputReader in;
    private PrintWriter out;

    Task(InputReader in, PrintWriter out) {
        this.in = in;
        this.out = out;
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

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

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

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

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

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

    public byte nextByte(){
        return Byte.parseByte(next());
    }
}


import java.io.*;

public class CF8C {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String s = br.readLine();
		int si = s.indexOf(' ', 0);
		int x = Integer.parseInt(s.substring(0, si));
		int y = Integer.parseInt(s.substring(si + 1));
		int n = Integer.parseInt(br.readLine());
		int[] xx = new int[n + 1];
		int[] yy = new int[n + 1];
		for (int i = 0; i < n; i++) {
			s = br.readLine();
			si = s.indexOf(' ', 0);
			xx[i] = Integer.parseInt(s.substring(0, si));
			yy[i] = Integer.parseInt(s.substring(si + 1));
		}
		xx[n] = x;
		yy[n] = y;
		int[][] dd = new int[n + 1][n + 1];
		for (int i = 0; i <= n; i++)
			for (int j = i + 1; j <= n; j++) {
				int dx = xx[i] - xx[j];
				int dy = yy[i] - yy[j];
				dd[i][j] = dx * dx + dy * dy;
			}
		int[] aa = new int[1 << n];
		int[] bb = new int[1 << n];
		for (int k = 1; k < 1 << n; k++) {
			int a = -1;
			for (int b = 0; b < n; b++)
				if ((k & 1 << b) > 0) {
					a = b;
					break;
				}
			int l = k ^ 1 << a;
			int d = dd[a][n] + dd[a][n];
			aa[k] = aa[l] + d;
			bb[k] = l;
			for (int b = a + 1; b < n; b++)
				if ((k & 1 << b) > 0) {
					l = k ^ 1 << a ^ 1 << b;
					d = dd[a][n] + dd[b][n] + dd[a][b];
					if (aa[l] + d < aa[k]) {
						aa[k] = aa[l] + d;
						bb[k] = l;
					}
				}
		}
		int k = (1 << n) - 1;
		System.out.println(aa[k]);
		StringBuilder sb = new StringBuilder();
		sb.append(0);
		while (k != 0) {
			int l = bb[k];
			int m = k ^ l;
			for (int b = 0; b < n; b++)
				if ((m & 1 << b) > 0)
					sb.append(' ').append(b + 1);
			sb.append(' ').append(0);
			k = l;
		}
		System.out.println(sb);
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            int bestC = best[set ^ (1 << i)] + single[i];
            int prevC = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            for (int j = i + 1, unoJ = 1 << (i + 1); j < n; ++j, unoJ <<= 1)
                if ((set & unoJ) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < bestC) {
                        bestC = cur;
                        prevC = unoI | unoJ;
                    }
                }
            best[set] = bestC;
            prev[set] = prevC;
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

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


import java.util.Scanner;

public class Problem_8C {
  private static int dis(int x1, int y1, int x2, int y2) {
    return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
  }

  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    int ox = sc.nextInt();
    int oy = sc.nextInt();
    int n = sc.nextInt();
    int[] ix = new int[n];
    int[] iy = new int[n];
    int[] single = new int[n];
    int[][] pair = new int[n][n];
    for (int i = 0; i < n; i++) {
      ix[i] = sc.nextInt();
      iy[i] = sc.nextInt();
      single[i] = dis(ox, oy, ix[i], iy[i]) * 2;
      for (int j = 0; j < i; j++) {
        pair[i][j] = pair[j][i] = dis(ix[i], iy[i], ix[j], iy[j]) + (single[i] + single[j]) / 2;
      }
    }
    int[] min = new int[1 << n];
    int[] pre = new int[1 << n];
    for (int set = 1; set < 1 << n; set++) {
      int i;
      for (i = 0; i < n; i++) {
        if ((set & (1 << i)) != 0) {
          break;
        }
      }
      min[set] = min[set ^ (1 << i)] + single[i];
      pre[set] = set ^ (1 << i);
      for (int j = 0; j < n; j++) {
        if ((set & (1 << j)) == 0) {
          continue;
        }
        if (min[set] > min[set ^ (1 << i) ^ (1 << j)] + pair[i][j]) {
          min[set] = min[set ^ (1 << i) ^ (1 << j)] + pair[i][j];
          pre[set] = set ^ (1 << i) ^ (1 << j);
        }
      }
    }
    System.out.println(min[(1 << n) - 1]);
    for (int set = (1 << n) - 1; set != 0; set = pre[set]) {
      System.out.print("0 ");
      for (int i = 0; i < n; i++) {
        if (((set ^ pre[set]) & (1 << i)) != 0) {
          System.out.print((i + 1) + " ");
        }
      }
    }
    System.out.println("0");
    sc.close();
  }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        int[] best = new int[1 << n];
        int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            best[set] = best[set ^ (1 << i)] + single[i];
            prev[set] = 1 << i;
            for (int j = i + 1; j < n; ++j)
                if ((set & (1 << j)) != 0) {
                    int cur = best[set ^ (1 << i) ^ (1 << j)] + pair[i][j];
                    if (cur < best[set]) {
                        best[set] = cur;
                        prev[set] = (1 << i) | (1 << j);
                    }
                }
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class LookingForOrder {

	static int[] dp = new int[(int) (1 << 24)];
	static int[][] points;
	static int[] sol = new int[1<<24];
	static int sx = 0, sy = 0;

	public static void main(String[] args) {

		sx = in.nextInt();
		sy = in.nextInt();
		Arrays.fill(dp, -2);

		int n = in.nextInt();
		points = new int[n][3];

		for (int i = 0; i < n; i++) {
			points[i][0] = in.nextInt();
			points[i][1] = in.nextInt();
			points[i][2] = (sx - points[i][0]) * (sx - points[i][0]) + (sy - points[i][1]) * (sy - points[i][1]);
		}

		//System.out.println("ANS");
		System.out.println(solve(0));

		int mask=0;
		while(true){
			System.out.print(0+" ");
			if (mask==(1<<n)-1) break;
			int x = sol[mask];
			int count=0;
			for(int i=0; i<n; i++){
				if ((x&(1<<i))!=0) {
					count++;
					System.out.print((i+1)+" ");
					mask|=(1<<i);
				}
				if (count==2) break;

			}
		}
		System.out.println();

	}

	public static int solve(int mask) {

		if (dp[mask]!=-2) return dp[mask];

		int n = points.length;
		if (mask == ((1 << n)-1)) {
			return dp[mask]=0;
		}

		int here = -1;
		for (int i = 0; i < n; i++) {
			if ((mask & (1<<i)) == 0) {
				here = i;
				break;
			}
		}

		int ans = 2*points[here][2]+solve(mask | (1 << here));
		sol[mask] = 1<<here;

		int x1 = points[here][0];
		int y1 = points[here][1];

		for (int i = here + 1; i < n; i++) {
			if ((mask & (1 << i)) == 0) {
				int x2 = points[i][0];
				int y2 = points[i][1];
				int p = mask|(1<<here);
				p = p|(1<<i);
				if (ans>points[here][2] + points[i][2] + (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
						+ solve(p)){
					ans=points[here][2] + points[i][2] + (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)
							+ solve(p);
					sol[mask]=(1<<here)|(1<<i);
				}
			}
		}

		return dp[mask]=ans;
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

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

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

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

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}

	}

	static MyScanner in = new MyScanner();

}


import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class CodeD
{
	static class Scanner
	{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer("");

		public String nextLine()
		{
			try
			{
				return br.readLine();
			}
			catch(Exception e)
			{
				throw(new RuntimeException());
			}
		}

		public String next()
		{
			while(!st.hasMoreTokens())
			{
				String l = nextLine();
				if(l == null)
					return null;
				st = new StringTokenizer(l);
			}
			return st.nextToken();
		}

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

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

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

		public int[] nextIntArray(int n)
		{
			int[] res = new int[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextInt();
			return res;
		}

		public long[] nextLongArray(int n)
		{
			long[] res = new long[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}

		public double[] nextDoubleArray(int n)
		{
			double[] res = new double[n];
			for(int i = 0; i < res.length; i++)
				res[i] = nextLong();
			return res;
		}
		public void sortIntArray(int[] array)
		{
			Integer[] vals = new Integer[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortLongArray(long[] array)
		{
			Long[] vals = new Long[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}

		public void sortDoubleArray(double[] array)
		{
			Double[] vals = new Double[array.length];
			for(int i = 0; i < array.length; i++)
				vals[i] = array[i];
			Arrays.sort(vals);
			for(int i = 0; i < array.length; i++)
				array[i] = vals[i];
		}
	}
	static final Scanner sc;
	static final int n;
	static final int[][] distancias;
	static final int[] distancia;
	static final int[] dp;
	static final int[] dpNext;
	static final int X;
	static final int Y;

	static
	{
		sc = new Scanner();
		X = sc.nextInt();
		Y = sc.nextInt();
		n = sc.nextInt();
		distancias = new int[n][n];
		distancia = new int[n];
		dp = new int[1 << n];
		Arrays.fill(dp, -1);
		dpNext = new int[1 << n];
	}

	static int dp(int mascara)
	{
		if(dp[mascara] != -1)
			return dp[mascara];
		int highest = -1;
		for(int i = 0, tmp = mascara; tmp != 0; i++, tmp >>= 1)
		{
			if((tmp & 1) == 1)
			{
				highest = i;
				break;
			}
		}
		if(highest == -1)
			return 0;
		int nextMsc = mascara ^ (1 << highest);
		int costHighest = distancia[highest];
		int best = (costHighest << 1) + dp(nextMsc);
		int bestNext = nextMsc;
		for(int i = 0, tmp = nextMsc, iC = 1; tmp != 0; i++, tmp >>= 1, iC <<= 1)
		{
			if((tmp & 1) == 1)
			{
				int msc = nextMsc ^ iC;
				int possibleA = costHighest + distancias[highest][i] + distancia[i] + dp(msc);
				if(possibleA < best)
				{
					best = possibleA;
					bestNext = msc;
				}
			}
		}
		dpNext[mascara] = bestNext;
		return dp[mascara] = best;

	}
	public static void main(String[] args)
	{
		int[][] objetos = new int[n][2];
		for(int i = 0; i < n; i++)
		{
			objetos[i][0] = sc.nextInt();
			objetos[i][1] = sc.nextInt();
			distancia[i] = (X - objetos[i][0]) * (X - objetos[i][0]) + (Y - objetos[i][1]) * (Y - objetos[i][1]);
		}
		for(int i = 0; i < n; i++)
			for(int j = 0; j < n; j++)
				distancias[i][j] = (objetos[i][0] - objetos[j][0]) * (objetos[i][0] - objetos[j][0]) + (objetos[i][1] - objetos[j][1]) * (objetos[i][1] - objetos[j][1]);
		int ans = dp((1 << n) - 1);
		System.out.println(ans);
		int current = (1 << n) - 1;
		while(current != 0)
		{
			int next = dpNext[current];
			int differents = next ^ current;
			System.out.print("0 ");
			for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
					System.out.print((i + 1) + " ");
			current = next;
		}
		System.out.println("0");
	}

}


import java.util.Scanner;

public class C {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int xs = sc.nextInt();
		int ys = sc.nextInt();
		int n = sc.nextInt();
		int[]x = new int[n], y = new int[n];
		for (int i = 0; i < n; i++) {
			x[i] = sc.nextInt();
			y[i] = sc.nextInt();
		}
		int[]single = new int[n];
		int[][]pair = new int[n][n];
		for (int i = 0; i < n; i++) {
			single[i] = 2*((x[i]-xs)*(x[i]-xs)+(y[i]-ys)*(y[i]-ys));
		}
		for (int i = 0; i < n; i++) {
			for (int j = i+1; j < n; j++) {
				pair[i][j] = (x[i]-xs)*(x[i]-xs)+(y[i]-ys)*(y[i]-ys)+(x[j]-xs)*(x[j]-xs)+(y[j]-ys)*(y[j]-ys)+(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
			}
		}
		int[]best = new int[1 << n], prev = new int[1 << n];
		for (int mask = 1; mask < (1 << n); mask++) {
			int i = 0;
			while ((mask & (1 << i))==0)
				i++;
			best[mask] = best[mask ^ (1 << i)]+single[i];
			prev[mask] = i+1;
			for (int j = i+1; j < n; j++) {
				if ((mask & (1 << j)) != 0) {
					int temp = best[mask ^ (1 << i) ^ (1 << j)]+pair[i][j];
					if (temp < best[mask]) {
						best[mask] = temp;
						prev[mask] = (i+1)*100+(j+1);
					}
				}
			}
		}
		System.out.println(best[(1 << n) - 1]);
		System.out.print("0 ");
		int cur = (1 << n) - 1;
		while (cur > 0) {
			int a = prev[cur]  % 100;
			int b = prev[cur] / 100;
			if (a > 0) {
				System.out.print(a+" ");
				cur ^= 1 << (a-1);
			}
			if (b > 0) {
				System.out.print(b+" ");
				cur ^= 1 << (b-1);
			}
			System.out.print(0+" ");
		}
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Bag implements Runnable {
    private void solve() throws IOException {
        int xs = nextInt();
        int ys = nextInt();
        int n = nextInt();
        int[] x = new int[n];
        int[] y = new int[n];
        for (int i = 0; i < n; ++i) {
            x[i] = nextInt();
            y[i] = nextInt();
        }
        final int[][] pair = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j = i + 1; j < n; ++j)
                pair[i][j] = (x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys) + (x[j] - xs) * (x[j] - xs) + (y[j] - ys) * (y[j] - ys) + (x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]);
        final int[] single = new int[n];
        for (int i = 0; i < n; ++i) {
            single[i] = 2 * ((x[i] - xs) * (x[i] - xs) + (y[i] - ys) * (y[i] - ys));
        }
        final int[] best = new int[1 << n];
        final int[] prev = new int[1 << n];
        for (int set = 1; set < (1 << n); ++set) {
            int i;
            for (i = 0; i < n; ++i)
                if ((set & (1 << i)) != 0)
                    break;
            int bestC = best[set ^ (1 << i)] + single[i];
            int prevC = 1 << i;
            int nextSet = set ^ (1 << i);
            int unoI = 1 << i;
            int msc = set >> (i + 1);
            for (int j = i + 1, unoJ = 1 << (i + 1); msc != 0 && j < n; ++j, unoJ <<= 1, msc >>= 1)
                if ((msc & 1) != 0) {
                    int cur = best[nextSet ^ unoJ] + pair[i][j];
                    if (cur < bestC) {
                        bestC = cur;
                        prevC = unoI | unoJ;
                    }
                }
            best[set] = bestC;
            prev[set] = prevC;
        }
        writer.println(best[(1 << n) - 1]);
        int now = (1 << n) - 1;
        writer.print("0");
        while (now > 0) {
        	int differents = prev[now];
        	for(int i = 0; i < n; i++)
				if((differents & (1 << i)) != 0)
				{
					 writer.print(" ");
		             writer.print(i + 1);
		             now ^= 1 << i;
				}
            writer.print(" ");
            writer.print("0");
        }
        writer.println();
    }

    public static void main(String[] args) {
        new Bag().run();
    }

    BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter writer;

    public void run() {
        try {
            reader = new BufferedReader(new InputStreamReader(System.in));
            tokenizer = null;
            writer = new PrintWriter(System.out);
            solve();
            reader.close();
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

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


import java.util.*;
import static java.lang.Math.*;

public class Main {

	static int hx, hy;
	static int[] X, Y;
	static int N;
	static int[] DP;

	static int pw(int a) {
		return a * a;
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		hx = sc.nextInt();
		hy = sc.nextInt();
		N = sc.nextInt();
		X = new int[N];
		Y = new int[N];
		for (int i = 0; i < N; ++i) {
			X[i] = sc.nextInt();
			Y[i] = sc.nextInt();
		}
		DP = new int[1 << N];
		Arrays.fill(DP, -1);
		int ans = recur(0);
		ArrayList<Integer> aa = new ArrayList<Integer>();
		int U = 0;
		aa.add(0);
		int test = 0;
		while (U != (1 << N) - 1) {
			int a = 0;
			for (int i = 0; i < N; ++i) {
				if (((1 << i) & U) == 0) {
					a = i;
					break;
				}
			}
			int ans2 = recur(U | (1 << a)) + 2 * (pw(X[a] - hx) + pw(Y[a] - hy));
			int temp = 2 * (pw(X[a] - hx) + pw(Y[a] - hy));
			int best = -1;
			for (int i = a + 1; i < N; ++i) {
				if (((1 << i) & U) == 0) {
					int ans3 = recur(U|(1<<a)|(1<<i)) + pw(X[a]-X[i])+pw(Y[a]-Y[i]) + pw(X[a]-hx)+pw(Y[a]-hy) + pw(X[i]-hx)+pw(Y[i]-hy);
					if (ans3 < ans2) {
						ans2 = ans3;
						ans2 = ans3;
						best = i;
						temp = pw(X[a]-X[i])+pw(Y[a]-Y[i]) + pw(X[a]-hx)+pw(Y[a]-hy) + pw(X[i]-hx)+pw(Y[i]-hy);
					}
				}
			}
			if (best == -1) {
				aa.add(a + 1);
				aa.add(0);
				U |= (1 << a);
			} else {
				aa.add(a + 1);
				aa.add(best + 1);
				aa.add(0);
				U |= (1 << a) | (1 << best);
			}
		}
		System.out.println(ans);
		for (int i = 0; i < aa.size(); ++i) {
			System.out.print(aa.get(i) + " ");
		}
	}

	private static int recur(int U) {
		if (DP[U] != -1) {
			return DP[U];
		}
		if (U == (1 << N) - 1) {
			return 0;
		}
		int a = 0;
		for (int i = 0; i < N; ++i) {
			if (((1 << i) & U) == 0) {
				a = i;
				break;
			}
		}
		int ans = recur(U | (1 << a)) + 2 * (pw(X[a] - hx) + pw(Y[a] - hy));
		for (int i = a + 1; i < N; ++i) {
			if (((1 << i) & U) == 0) {
				ans = min(ans, recur(U|(1<<a)|(1<<i)) + pw(X[a]-X[i])+pw(Y[a]-Y[i]) + pw(X[a]-hx)+pw(Y[a]-hy) + pw(X[i]-hx)+pw(Y[i]-hy));
			}
		}
		DP[U] = ans;
		return ans;
	}
}


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class cf8c {
  static int n;
  static int[] bb;
  static int[] memo;
  static int[][] cost;
  static FastIO in = new FastIO(), out = in;
  public static void main(String[] args) {
    vec2 cen = new vec2(in.nextInt(),in.nextInt());
    n = in.nextInt();
    cost = new int[n][n];
    vec2[] v = new vec2[n];
    for(int i=0; i<n; i++)
      v[i] = new vec2(in.nextInt(),in.nextInt());
    for(int i=0; i<n; i++)
      for(int j=0; j<n; j++)
        cost[i][j] = v[i].dist(cen) + v[i].dist(v[j]) + v[j].dist(cen);
    memo = new int[1<<n];
    bb = new int[1<<n];
    Arrays.fill(memo,-1);
    out.println(go(0));
    build(0);
    out.close();
  }
  static void build(int mask) {
    if(mask == (1<<n)-1) {
      out.println(0);
      return;
    }
    int first = 0;
    while((mask & (1<<first)) != 0) first++;
    int second = bb[mask];
    out.print("0 " + (first+1) + " ");
    if(second != first)
      out.print((second+1)+" ");
    build(mask|(1<<first)|(1<<second));
  }
  static int go(int mask) {
    if(mask == (1<<n)-1) return 0;
    if(memo[mask] != -1) return memo[mask];
    int first = 0;
    int ans = Integer.MAX_VALUE;
    while((mask & (1<<first)) != 0) first++;
    for(int second = first; second < n; second++) {
      if((mask & (1<<second)) != 0) continue;
      int tans = cost[first][second] + go(mask|(1<<first)|(1<<second));
      if(tans < ans) {
        ans = tans;
        bb[mask] = second;
      }
    }
    return memo[mask] = ans;
  }
  static class vec2 {
    int x, y;
    vec2(int a, int b) {
      x = a; y = b;
    }
    vec2 sub(vec2 v) {
      return new vec2(x-v.x,y-v.y);
    }
    int dist(vec2 v) {
      return sub(v).mag2();
    }
    int mag2() {
      return x*x+y*y;
    }
  }
  static class FastIO extends PrintWriter {
    BufferedReader br;
    StringTokenizer st;

    public FastIO() {
      this(System.in,System.out);
    }
    public FastIO(InputStream in, OutputStream out) {
      super(new BufferedWriter(new OutputStreamWriter(out)));
      br = new BufferedReader(new InputStreamReader(in));
      scanLine();
    }
    public void scanLine() {
      try {
        st = new StringTokenizer(br.readLine().trim());
      } catch(Exception e) {
        throw new RuntimeException(e.getMessage());
      }
    }
    public int numTokens() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return numTokens();
      }
      return st.countTokens();
    }
    public String next() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return next();
      }
      return st.nextToken();
    }
    public double nextDouble() {
      return Double.parseDouble(next());
    }
    public long nextLong() {
      return Long.parseLong(next());
    }
    public int nextInt() {
      return Integer.parseInt(next());
    }
  }
}


import java.util.InputMismatchException;
import java.io.*;
import java.util.Vector;
import java.util.Collections;
import java.util.Arrays;

/**
 * Generated by Contest helper plug-in
 * Actual solution is at the bottom
 */
public class Main {
    public static void main(String[] args) {
        InputReader in = new StreamInputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        run(in, out);
    }

    public static void run(InputReader in, PrintWriter out) {
        Solver solver = new Sellerman();
        solver.solve(1, in, out);
        Exit.exit(in, out);
    }
}

class StreamInputReader extends InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar, numChars;

    public StreamInputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    @Override
    public void close() {
        try {
            stream.close();
        } catch (IOException ignored) {
        }
    }
}

abstract class InputReader {
    private boolean finished = false;

    public abstract int read();

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

    public String nextToken() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }
    private boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public void setFinished(boolean finished) {
        this.finished = finished;
    }

    public abstract void close();
}

interface Solver {
    public void solve(int testNumber, InputReader in, PrintWriter out);
}

class Exit {
    private Exit() {
    }

    public static void exit(InputReader in, PrintWriter out) {
        in.setFinished(true);
        in.close();
        out.close();
    }
}

class Sellerman implements Solver {

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int x0 = in.nextInt();
        int y0 = in.nextInt();
        int n = in.nextInt() + 1;
        int[] x = new int[n];
        int[] y = new int[n];
        x[n - 1] = x0;
        y[n - 1] = y0;
        for (int i = 0; i < n - 1; ++i) {
            x[i] = in.nextInt();
            y[i] = in.nextInt();
        }
        int [][] g = new int[n][n];
        for(int i = 0; i < n; ++i)
            for (int j = 0; j < n; ++j) {
                g[i][j] = (x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]);
            }
        -- n;
        int[] dm = new int[1 << n];
        int[] prev = new int[1 << n];
        byte [] bit = new byte[1 << n];
        byte [] item0 = new byte[1 << n];
        byte [] item1 = new byte[1 << n];
        for (int i = 0; i < n; ++i) {
            bit[1 << i] = (byte) i;
        }
        Arrays.fill(dm, -1);
        dm[0] = 0;
        int tt[][] = new int[n][n];
        for (int i = 0; i < n; ++i)
            for (int j =0 ; j < n; ++j) {
                tt[i][j] = Math.min(g[n][i] + g[i][j] + g[j][n],
                                    g[n][j] + g[i][j] + g[i][n]);
            }
        for (int i = 0; i < (1 << n); ++i) {
            if (dm[i] == -1)continue;
            int t = (i ^ ((1 << n) - 1));
            int left = bit[t - (t & (t - 1))];
            for (int j = left; j < n; ++j) {
                if ((i & (1 << j)) > 0) continue;
                int nm = i | (1 << left) | (1 << j);
                if (dm[nm] == -1 || dm[nm] > dm[i] + tt[left][j]) {
                    dm[nm] = dm[i] + tt[left][j];
                    prev[nm] = i;
                    item0[nm] = (byte)left;
                    item1[nm] = (byte)j;
                }
            }
        }
        out.println(dm[(1 << n) - 1]);
        Vector<Vector<Integer>> path = new Vector<Vector<Integer>> () ;
        int cmask = (1 << n) - 1;
        while (cmask > 0) {
            int p = prev[cmask];
            Vector<Integer> tmp = new Vector<Integer> () ;
            tmp.add(0);
            tmp.add(item0[cmask] + 1);
            tmp.add(item1[cmask] + 1);
            cmask = prev[cmask];
            path.add(tmp);
        }
        Collections.reverse(path);
        int len = 0;
        for (Vector<Integer> vec : path)
            len += vec.size();
        int ans[] = new int[len];
        boolean[] valid = new boolean[len];
        Arrays.fill(valid, true);
        len = 0;
        for (Vector<Integer> vec : path) {
            for (int ttt : vec) {
                ans[len ++] = ttt;
            }
        }
        for (int i = 0; i < len - 1; ++i) {
            if (ans[i] == ans[i + 1])
                valid[i] = false;
        }
        for (int i = 0; i < len; ++i) {
            if (valid[i]) {
                out.print(ans[i] + " ");
            }
        }
        out.print("0");

    }
}