You have r red, g green and b blue balloons. To decorate a single table for the banquet you need exactly three balloons. Three balloons attached to some table shouldn't have the same color. What maximum number t of tables can be decorated if we know number of balloons of each color?Your task is to write a program that for given values r, g and b will find the maximum number t of tables, that can be decorated in the required manner.

The single line contains three integers r, g and b (0 ≤ r, g, b ≤ 2·109) — the number of red, green and blue baloons respectively. The numbers are separated by exactly one space.

Print a single integer t — the maximum number of tables that can be decorated in the required manner.

NoteIn the first sample you can decorate the tables with the following balloon sets: "rgg", "gbb", "brr", "rrg", where "r", "g" and "b" represent the red, green and blue balls, respectively.

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

public class Main {

    static FastReader in = new FastReader(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(System.out);
    static int maxn = (int)1e5 + 111;
    static int inf = (1<<30)-1;
    static long n,ans;
    static long a[] = new long [5];
    public static void main (String [] args) throws Exception {

//      in = new FastReader(new BufferedReader(new FileReader("input.txt")));
//      out = new PrintWriter ("output.txt");
//
        n = 3;

        for (int i=1; i<=n; i++) {
            a[i] = in.nextLong();
        }

        Arrays.sort(a,1,(int)n+1);

        long t = a[3]-a[2];
        t = Math.min(t/2, a[1]);

        ans += t;

        a[3] -= (t) * 2;
        a[1]-=t;
        a[2] -= a[1];
        a[3] -= a[1];
        ans+=a[1];
        a[1] = 0;

        Arrays.sort(a,1,(int)n+1);

        ans += Math.min((a[2]+a[3])/3, a[2]);

        out.println(ans);
        out.close();

    }
}

class Pair {
    int l,r;
    public Pair (int l, int r) {
        this.l = l;
        this.r = r;
    }
}

class FastReader {

    BufferedReader bf;
    StringTokenizer tk = null;
    String DELIM = " ";

    public FastReader (BufferedReader bf) {
        this.bf = bf;
    }

    public String nextToken() throws Exception  {
        if (tk==null || !tk.hasMoreTokens()) {
            tk = new StringTokenizer(bf.readLine(), DELIM);
        }
        return tk.nextToken();
    }

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

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

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

}

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

public class C {

	static class Scanner{
		BufferedReader br=null;
		StringTokenizer tk=null;
		public Scanner(){
			br=new BufferedReader(new InputStreamReader(System.in));
		}
		public String next() throws IOException{
			while(tk==null || !tk.hasMoreTokens())
				tk=new StringTokenizer(br.readLine());
			return tk.nextToken();
		}
		public int nextInt() throws NumberFormatException, IOException{
			return Integer.valueOf(next());
		}
		public long nextLong() throws NumberFormatException, IOException{
			return Long.valueOf(next());
		}
		public double nextDouble() throws NumberFormatException, IOException{
			return Double.valueOf(next());
		}
	}

	public static void main(String args[]) throws NumberFormatException, IOException{
		Scanner sc = new Scanner();
		long[] a = new long[3];
		for(int i = 0; i < 3; i++)
			a[i] = sc.nextLong();
		Arrays.sort(a);
		if( 2*a[0] + 2*a[1] <= a[2])
			System.out.println(a[0] + a[1]);
		else
			System.out.println((a[0] + a[1] + a[2])/3);
	}

}

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

/**
 *
 * @author Saju
 *
 */

public class Main {

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

    private static final long INF = Long.MAX_VALUE;
    private static final int INT_INF = Integer.MAX_VALUE;
    private static final long NEG_INF = Long.MIN_VALUE;
    private static final int NEG_INT_INF = Integer.MIN_VALUE;
    private static final double EPSILON = 1e-10;

    private static final int MAX = 1000005;

    private static final long MOD = 1000000007;

    private static final int MAXN = 100007;
    private static final int MAXA = 10000009;
    private static final int MAXLOG = 22;

	public static void main(String[] args) throws IOException {

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

//         InputReader in = new InputReader(new FileInputStream("src/test.in"));
//         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("src/test.out")));

/*

500000000
1000000000
500000000

*/

		long r = in.nextLong();
		long g = in.nextLong();
		long b = in.nextLong();

		long res = 0;
		if(max(r, max(g, b)) >= 2 * (r + g + b - max(r, max(g, b)))) {
			res = max(res, r + g + b - max(r, max(g, b)));
		}
		else {
			res = max(res, (r + g + b) / 3);
		}
		out.println(res);

		in.close();
		out.flush();
		out.close();
		System.exit(0);
	}

	private static long c(long tempG, long tempB) {
		long min = min(tempG, tempB);
		long max = max(tempG, tempB);
		long temp = 0;
		if(2L * min <= max) {
			temp = min;
		}
		else if(max / 2L <= min){
			temp = max / 2L;
			long a = min - temp;
			long b = max - (2 * temp);
			temp += d(a, b);
			if(b - a <= 1) {
				temp = max(temp, (min + max) / 3);
			}
			else {
				temp = max(temp, (min + (min + 1)) / 3);
			}
		}

//		System.out.println(temp);

		return temp;
	}

	private static long d(long a, long b) {
		long min = min(a, b);
		long max = max(a, b);
		long temp = 0;
		if(2L * min <= max) {
			temp = min;
		}
		else if(max / 2L <= min){
			temp = max / 2L;

		}
//		System.out.println(temp);
		return temp;
	}

	private static class Pair{
		int a;
		int b;
		Pair(int a, int b){
			this.a = a;
			this.b = b;
		}
	}

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

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

	private static long ceil(long n, long x) {
		long div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
	}

    private static int ceil(int n, int x) {
        int div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
    }

    private static class Point {
        double x;
        double y;

        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        double getDistance(Point p2) {
            Point p1 = this;
            double dx = p1.x - p2.x;
            double dy = p1.y - p2.y;

            return Math.sqrt((dx * dx) + (dy * dy));
        }
    }

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

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

    private static int lcm(int a, int b) {
        return (a * b) / gcd(a, b);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        	}

        }
    }

}

import java.util.Scanner;

public class b {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
	int m=sc.nextInt();
	int a[]=new int [3];
	a[0]=m;
	int g=0;

	for(int i=1;i<3;i++)
	{
		a[i]=sc.nextInt();
		if(a[i]>m)
		{
			m=a[i];
		g=i;
	}
	}
	long s=0;
	for(int i=0;i<3;i++)
	{
		if(i==g)
		{

		}
		else
			s=s+a[i];
	}
	//System.out.println((m));

		if((2*s)<m)
		{
			System.out.println(s);
		}
		else
		{
			System.out.println((s+m)/3);
		}
	}
}

import java.awt.Point;
import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastReader sc = new FastReader();
        long[] arr=new long[3];
        for(int i=0;i<3;i++)arr[i]=sc.nextInt();
        Arrays.sort(arr);
        if(arr[2]/2>=arr[1]+arr[0]) System.out.println(arr[1]+arr[0]);
        else System.out.println((arr[0]+arr[1]+arr[2])/3);
    }
}

class FastReader {
    BufferedReader br;
    StringTokenizer st;

    public FastReader() {
        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;
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            long r = s.nextLong();
            long g = s.nextLong();
            long b = s.nextLong();

            long ans = (r + g + b) / 3;
            long[] arr = new long[3];
            arr[0] = r;
            arr[1] = g;
            arr[2] = b;

            Arrays.sort(arr);
            out.println(Math.min(ans, arr[0] + arr[1]));
        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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++];
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

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

public class A {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] a = new long[] { in.nextInt(), in.nextInt(), in.nextInt() };
        Arrays.sort(a);
        System.out.println(Math.min((a[0] + a[1] + a[2]) / 3, a[0] + a[1]));
    }

}

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

/**
 * Created by msi on 4/2/2017.
 */
public class TableDecorations2 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] colors = new long[3];
        colors[0] = in.nextInt();
        colors[1] = in.nextInt();
        colors[2] = in.nextInt();

        Arrays.sort(colors);
        if ((colors[0] + colors[1]) * 2 <= colors[2]) {
            System.out.println(colors[0] + colors[1]);
        } else {
            System.out.println((colors[0] + colors[1] + colors[2]) / 3);
        }

    }
}

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long[] a = new long[3];
        for (int i = 0; i < 3; i++) {
            a[i] = in.readLong();
        }
        Arrays.sort(a);
        long res = Math.min((a[0] + a[1] + a[2]) / 3, a[0] + a[1]);
        out.printLine(res);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(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++];
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author AlexFetisov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long[] a = new long[]{in.nextLong(), in.nextLong(), in.nextLong()};

        Arrays.sort(a);

        long res = (a[0] + a[1] + a[2]) / 3;
        if (a[2] > 2L * (a[0] + a[1])) {
            res = a[0] + a[1];
        }
        out.println(res);
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

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

    public String nextLine() {
        try {
            return reader.readLine().trim();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

}

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

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] rgb = new long[3];
        long min = Long.MAX_VALUE;
        long max = Long.MIN_VALUE;
        long answer = 0;
        long sum = 0;
        for (int i = 0; i < 3; i++) {
            rgb[i] = in.nextLong();
            sum += rgb[i];
            if (rgb[i] < min) min = rgb[i];
            if (rgb[i] > max) max = rgb[i];
        }
        if (max - min <= 1) {
            System.out.println(sum / 3);
            System.exit(0);
        }
        else {
            Arrays.sort(rgb);
            int zero_count = 0;
            for (int i = 0; i < 3; i++) if (rgb[i] == 0) zero_count++;
            while (zero_count < 2) {
                while ((rgb[2] >= 2 && rgb[1] >= 1) || (rgb[2] >= 1 && rgb[1] >= 2)) {
                    int rank = (int) Math.pow(10,(int) Math.ceil(Math.log10(rgb[1]) - 2));
                    if (rank <= 0) rank = 1;
                    if (rgb[2] > rgb[1]) {
                        rgb[2] -= 2 * rank;
                        rgb[1] -= 1 * rank;
                        answer += 1 * rank;
                    }
                    else {
                        rgb[2] -= 1 * rank;
                        rgb[1] -= 2 * rank;
                        answer += 1 * rank;
                    }
                    Arrays.sort(rgb);
                }
                if (rgb[0] == rgb[1] && rgb[1] == rgb[2] && rgb[2] == 1) {
                    answer++;
                    zero_count = 3;
                }
                zero_count++;
            }
        }
        System.out.println(answer);
        System.exit(0);
    }
}

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		if (System.getProperty("ONLINE_JUDGE") == null) {
			inputStream = new FileInputStream("input.inp");
			// outputStream = new FileOutputStream("output.out");
		} else {
			inputStream = System.in;
			outputStream = System.out;
		}
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(in, out);
		out.close();
	}

	static final int N = 100005;
	static final int oo = 1000000007;
	static final double pi = Math.acos(-1);

	static class Task {
		public int get(int x, int y) {
			if (x <= 0 || y <= 0) return 0;
			return Math.min((x + y) / 3, x);
		}

		public void solve(InputReader in, PrintWriter out) {
			int[] a = new int[3];
			for (int i = 0; i < 3; ++i) a[i] = in.nextInt();
			long ans = 0;
			Arrays.sort(a);
			ans = Math.min(((long) a[0] + a[1] + a[2]) / 3, (long) a[0] + a[1]);
			out.print(ans);
		}
	}

	static 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 int nextInt() {
			return Integer.parseInt(next());
		}

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

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

		public char nextChar() {
			return next().charAt(0);
		}
	}
}

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

public class Main {

	  public static String binary = "";
	  //System.out.println(ans);
	  public static int gcd(int a,int b){
		if(a == 0)
			return b;
		return gcd(b % a, a);
	  }

	  private static void Binaryform(int number) {
        int remainder;
        if (number <= 1) {
            binary += number;
            return;
        }
        remainder = number %2;
        Binaryform(number >> 1);
        binary += remainder +"";
      }

	  public static void print(Object o){
		System.out.print(o +" ");
	  }

	  public static void println(Object o){
		System.out.println(o);
	  }

	  public  static class Point{
			  public int x = 0;
			  public int y = 0;

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

			}

		public static int isSquare(Point p1, Point p2,Point p3,Point p4){
			double dx = 0, dy = 0;
			double dd [] = new double [6];
			Point [] pp = new Point[4];
			pp[0]=p1; pp[1]=p2; pp[2]=p3; pp[3]=p4;
			int ii = 0; int jj = 0; int kk = 0; int nn = 0;

			for(ii = 0; ii < 3; ii++){
				for(jj = ii + 1; jj < 4; jj++){
					dx = pp[ii].x - pp[jj].x;
					dy = pp[ii].y - pp[jj].y;
					dd[kk] = dx*dx + dy*dy;
					if(dd[kk] == 0) return 0;
					if(kk > 1){
						for(nn = 0; nn < kk - 1; nn++){
							if (!( (2*dd[nn] == dd[kk] ) || (dd[nn] == dd[kk]) || (2*dd[kk] == dd[nn] )) )
								return 0;
						}
					}
					kk += 1;
				}
			}
			return 1;
		}

	  /*
	   4
		2 3 4 9
		1 3
	   */
      public static void main(String arg[]){
		Scanner in = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		long [] v = new long[]{in.nextLong(), in.nextLong(), in.nextLong() };

		Arrays.sort(v);
		long suma = 0;
		for(int i =0; i < 3; i++){
			suma += v[i];
		}
		suma /= 3;
		if(v[2] / 2 >= v[0] + v[1]){
			out.println(v[0] + v[1]);
		}
		else out.println(suma);
		in.close();
		out.close();
	  }

//2000000000 2000000000 2000000000

}

import java.util.Arrays;
import java.util.Scanner;
/**
 * Created by yakoub on 03/04/15.
 */
public class TableDecorations {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        long[] arr = new long[3];
        for (int i = 0; i < 3; i++)
            arr[i] = scanner.nextInt();
        Arrays.sort(arr);
        if (arr[0] + arr[1] <= arr[2] / 2)
            System.out.println(arr[0]+arr[1]);
        else
            System.out.println((arr[0]+arr[1]+arr[2])/3);
    }
}

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

public class TableDecorations {

    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));
        String[] strings = reader.readLine().split(" ");
        long[] is = new long[3];
        int index = 0;
        for (String string : strings) {
            is[index++] = Long.valueOf(string);
        }
        Arrays.sort(is);
        long sum = 0;
        if ((is[2] / 2) >= (is[0] + is[1])) {
            sum += is[0] + is[1];
        } else {
            for (long i : is) {
                sum += i;
            }
            sum /= 3;
        }
        System.out.println(sum);
    }
}

import java.util.*;

public class TableDecorations {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long arr[] = new long[3];
        long ans = 0;
        for (int i = 0; i < 3; i++) {
            arr[i] = in.nextInt();
            ans += arr[i];
        }
        System.out.println(Math.min(arr[0]+arr[1],Math.min(arr[1]+arr[2],Math.min(arr[2]+arr[0],(ans)/3))));
    }
}

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

/**
 * Created by matthew on 10/16/14.
 */
public class TableDecorations {
    public static void main(String[] args) {
        MyScanner in = new MyScanner();
        out = new PrintWriter(new BufferedOutputStream(System.out));
        String[] input = in.nextLine().split(" ");
        long[] rgb = new long[] {Integer.parseInt(input[0]),Integer.parseInt(input[1]),Integer.parseInt(input[2])};

        Arrays.sort(rgb);

        long sum = rgb[0] + rgb[1] + rgb[2];
        out.println(sum/3 < rgb[0] + rgb[1] ? sum/3 : rgb[0] + rgb[1]);

        out.close();
    }

    public static PrintWriter out;

    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;
        }
    }
}

import java.util.Scanner;

public class Table_Decorations {

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

		long r = in.nextLong(), g = in.nextLong(), b = in.nextLong();

		System.out.println(Math.min(Math.min(Math.min(r+g, r+b), b+g), (r+b+g)/3));
	}

}

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

public class Main {

	static long sx = 0, sy = 0, mod = (long) (1e9 + 7);

	// static ArrayList<Integer>[] a;
	static long[][][] dp;
	static long[] fa;
	static long[] farr;
	public static PrintWriter out;
	static ArrayList<pair> pa = new ArrayList<>();
	static long[] fact = new long[(int) 1e6];
	static StringBuilder sb = new StringBuilder();
	static boolean cycle = false;
	static long m = 998244353;
	static long[] no, col;
	// static String s;
	static int k = 0, n = 0;
	static int[] c;
	static long ans = 0;
	static HashMap<Integer, Integer> hm;
	static long[] arr;;
	static int[] depth;
	static int[] a;
	static int[][] p;
	static int[][] s;

	public static void main(String[] args) throws IOException {

		// Scanner scn = new Scanner(new BufferedReader(new
		// InputStreamReader(System.in)));

		out = new PrintWriter(System.out);
		Reader scn = new Reader();

		long[] a = new long[3];

		for (int i = 0; i < 3; i++)
			a[i] = scn.nextLong();

		Arrays.sort(a);

		if (a[2] == 0 || a[1] == 0)
			System.out.println(0);

		else if (a[1] == 0)
			System.out.println(Math.min(a[2] / 2, a[1]));

		else if (a[2] >= 2 * (a[0] + a[1])) {
			System.out.println(a[0] + a[1]);
		}

		else
			System.out.println((a[0] + a[1] + a[2]) / 3);

		out.close();

	}

	// _________________________TEMPLATE_____________________________________________________________

	// public static long lcm(long x, long y) {
	//
	// return (x * y) / gcd(x, y);
	// }
	//
	// private static long gcd(long x, long y) {
	// if (x == 0)
	// return y;
	//
	// return gcd(y % x, x);
	// }
	//
	// static class comp implements Comparator<pair> {
	//
	// @Override
	// public int compare(pair p1, pair p2) {
	// return p1.i - p2.i;
	// }
	//
	// }
	//
	// public static long pow(long a, long b) {
	//
	// if (b < 0)
	// return 0;
	// if (b == 0 || b == 1)
	// return (long) Math.pow(a, b);
	//
	// if (b % 2 == 0) {
	//
	// long ret = pow(a, b / 2);
	// ret = (ret % mod * ret % mod) % mod;
	// return ret;
	// }
	//
	// else {
	// return ((pow(a, b - 1) % mod) * a % mod) % mod;
	// }
	// }

	private static class pair implements Comparable<pair> {

		long no;
		long s, e;

		pair(long n, long c, long d) {
			no = n;
			s = c;
			e = d;

		}

		@Override
		public int compareTo(pair o) {

			return 1;

		}

		// @Override
		//
		// public int hashCode() {
		// return i;
		// }
		//
		// @Override
		//
		// public boolean equals(Object o) {
		//
		// pair p = (pair) o;
		// return this.i == p.i;
		// }

	}

	private static String reverse(String s) {

		return new StringBuilder(s).reverse().toString();
	}

	public static class Reader {
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public Reader() {
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader(String file_name) throws IOException {
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String readLine() throws IOException {
			byte[] buf = new byte[1000000 + 1]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1) {
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (c == '.') {
				while ((c = read()) >= '0' && c <= '9') {
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException {
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException {
			if (din == null)
				return;
			din.close();
		}

		public int[] nextIntArray(int n) throws IOException {
			int[] arr = new int[n];
			for (int i = 0; i < n; i++) {
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n) throws IOException {
			long[] arr = new long[n];
			for (int i = 0; i < n; i++) {
				arr[i] = nextLong();
			}
			return arr;
		}

		public int[][] nextInt2DArray(int m, int n) throws IOException {
			int[][] arr = new int[m][n];
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++)
					arr[i][j] = nextInt();
			}
			return arr;
		}

		public long[][] nextInt2DArrayL(int m, int n) throws IOException {
			long[][] arr = new long[m][n];
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++)
					arr[i][j] = nextInt();
			}
			return arr;
		}
		// kickstart - Solution
		// atcoder - Main
	}

}

import java.util.*;
import java.io.*;
public class typo
{
    static  class InputReader {
        private InputStream stream;
        private byte[] inbuf = new byte[1024];
        private int start= 0;
        private int end = 0;

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

        private int readByte() {
            if (start == -1) throw new UnknownError();
            if (end >= start) {
                end= 0;
                try {
                    start= stream.read(inbuf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (start<= 0) return -1;
            }
            return inbuf[end++];
        }

        private boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }
    }
    public static void main(String args[])
    {
        InputReader sc=new InputReader(System.in);
        long n1=sc.nextLong();
        long n2=sc.nextLong();
        long n3=sc.nextLong();
        long n4=(n1+n2+n3)-Math.max(n1,Math.max(n2,n3));
        long n5=(n1+n2+n3)/3;
        System.out.println(Math.min(n4,n5));
    }
}

import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class A {
    public static void main(String[] args) throws Exception {
         BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        // Scanner scan = new Scanner(System.in);
        // PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        // int n = Long.parseLong(bf.readLine());
        StringTokenizer st = new StringTokenizer(bf.readLine());
        // int[] a = new int[n]; for(int i=0; i<n; i++) a[i] = Long.parseLong(st.nextToken());
        long a = Long.parseLong(st.nextToken());
         long b = Long.parseLong(st.nextToken());
         long c = Long.parseLong(st.nextToken());
         long sum = a+b+c;
         if(a > 2*b+2*c) sum -= a-2*b-2*c;
         else if(b > 2*a+2*c) sum -= b-2*a-2*c;
         else if(c > 2*b+2*a) sum -= c-2*b-2*a;
         System.out.println(sum/3);
        // int n = scan.nextInt();

        // out.close(); System.exit(0);
    }
}

import java.util.StringTokenizer;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.*;

public class Main {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		long sum=0;
		long[] color = new long[3];
		color[0] = sc.nextInt();
		color[1] = sc.nextInt();
		color[2] = sc.nextInt();
		Arrays.sort(color);

		if((color[0]+color[1])*2<=color[2])
			sum= color[0]+color[1];
		else sum = (color[0]+color[1]+color[2])/3;
		System.out.println(sum);

	}
}

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

public class cf3 implements Runnable {

	public void run(){

		InputReader in =  new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);
		long r=in.nextLong();
		long g=in.nextLong();
		long b=in.nextLong();

		long[] a= {r,g,b};
		Arrays.sort(a);

		long ans=0;

		if(2*(a[0]+a[1]) <= a[2])
			w.println(a[0]+a[1]);
		else
			w.println((a[0]+a[1]+a[2])/3);
		w.close();

	}

	static class InputReader {

		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;

		public InputReader(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++];
		}

		public String nextLine()
		{
			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
		}
		public int nextInt()
		{
			int c = read();

			while(isSpaceChar(c))
				c = read();

			int sgn = 1;

			if (c == '-')
			{
				sgn = -1;
				c = read();
			}

			int res = 0;
			do
			{
				if(c<'0'||c>'9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));

			return res * sgn;
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			long res = 0;

			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
				return res * sgn;
		}

		public double nextDouble()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.')
			{
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.')
			{
				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

		public String readString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			}
			while (!isSpaceChar(c));

			return res.toString();
		}

		public boolean isSpaceChar(int c)
		{
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public String next()
		{
			return readString();
		}

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}
	}

	public static void main(String args[]) throws Exception
	{
		new Thread(null, new cf3(),"cf3",1<<26).start();
	}
 }

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 {

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

        long arr[]=new long [3];
        arr[0]=sc.nextInt();
        arr[1]=sc.nextInt();
        arr[2]=sc.nextInt();
        long  min= Math.min((arr[0] + arr[1] + arr[2]), 3 * Math.min(arr[0] + arr[1], Math.min(arr[0]+arr[2], arr[2]+arr[1])))/3;

        out.println(min);

        out.flush();
        out.close();

    }

    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
        {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if(x.charAt(0) == '-')
            {
                neg = true;
                start++;
            }
            for(int i = start; i < x.length(); i++)
                if(x.charAt(i) == '.')
                {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                }
                else
                {
                    sb.append(x.charAt(i));
                    if(dec)
                        f *= 10;
                }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg?-1:1);
        }

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

    }
}

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

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {

	int[] arr;

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		arr=new int[3];
		for (int i=0; i<3; i++) arr[i]=in.readInt();
		Arrays.sort(arr);
		out.printLine(MiscUtils.min(ArrayUtils.sumArray(arr)/3, 1L*arr[0]+arr[1]));
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
				outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(char[] array) {
		writer.print(array);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void print(int[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(long[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(IntCollection collection) {
		boolean first = true;
		for (IntIterator iterator = collection.iterator(); iterator.isValid(); iterator
				.advance()) {
			if (first)
				first = false;
			else
				writer.print(' ');
			writer.print(iterator.value());
		}
	}

	public void printLine(int[] array) {
		print(array);
		writer.println();
	}

	public void printLine(long[] array) {
		print(array);
		writer.println();
	}

	public void printLine(IntCollection collection) {
		print(collection);
		writer.println();
	}

	public void printLine() {
		writer.println();
	}

	public void printLine(Object... objects) {
		print(objects);
		writer.println();
	}

	public void print(char i) {
		writer.print(i);
	}

	public void printLine(char i) {
		writer.println(i);
	}

	public void printLine(char[] array) {
		writer.println(array);
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

	public void close() {
		writer.close();
	}

	public void flush() {
		writer.flush();
	}

	public void print(long i) {
		writer.print(i);
	}

	public void printLine(long i) {
		writer.println(i);
	}

	public void print(int i) {
		writer.print(i);
	}

	public void printLine(int i) {
		writer.println(i);
	}
}

class InputReader {
	private boolean finished = false;

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(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++];
	}

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

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}

	public String next() {
		return readString();
	}

	public SpaceCharFilter getFilter() {
		return filter;
	}

	public void setFilter(SpaceCharFilter filter) {
		this.filter = filter;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class ArrayUtils {
	public static Integer[] generateOrder(int size) {
		Integer[] order = new Integer[size];
		for (int i = 0; i < size; i++)
			order[i] = i;
		return order;
	}

	public static void fillColumn(long[][] array, int index, long value) {
		for (long[] row : array)
			row[index] = value;
	}

	public static void fillColumn(int[][] array, int index, int value) {
		for (int[] row : array)
			row[index] = value;
	}

	public static long sumArray(int[] array) {
		long result = 0;
		for (int element : array)
			result += element;
		return result;
	}

	public static int[] range(int from, int to) {
		int[] result = new int[Math.max(from, to) - Math.min(from, to) + 1];
		int index = 0;
		if (to > from) {
			for (int i = from; i <= to; i++)
				result[index++] = i;
		} else {
			for (int i = from; i >= to; i--)
				result[index++] = i;
		}
		return result;
	}

	public static long multiply(int[] first, int[] second) {
		long result = 0;
		for (int i = 0; i < first.length; i++)
			result += (long) first[i] * second[i];
		return result;
	}

	public static int[] createOrder(int size) {
		int[] order = new int[size];
		for (int i = 0; i < size; i++)
			order[i] = i;
		return order;
	}

	public static int[] sort(int[] array, IntComparator comparator) {
		return sort(array, 0, array.length, comparator);
	}

	public static int[] sort(int[] array, int from, int to,
			IntComparator comparator) {
		if (from == 0 && to == array.length)
			new IntArray(array).inPlaceSort(comparator);
		else
			new IntArray(array).subList(from, to).inPlaceSort(comparator);
		return array;
	}

	public static int[] unique(int[] array) {
		return unique(array, 0, array.length);
	}

	public static int[] unique(int[] array, int from, int to) {
		if (from == to)
			return new int[0];
		int count = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				count++;
		}
		int[] result = new int[count];
		result[0] = array[from];
		int index = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				result[index++] = array[i];
		}
		return result;
	}

	public static char[] unique(char[] array) {
		return unique(array, 0, array.length);
	}

	public static char[] unique(char[] array, int from, int to) {
		if (from == to)
			return new char[0];
		int count = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				count++;
		}
		char[] result = new char[count];
		result[0] = array[from];
		int index = 1;
		for (int i = from + 1; i < to; i++) {
			if (array[i] != array[i - 1])
				result[index++] = array[i];
		}
		return result;
	}

	public static int maxElement(int[] array) {
		return maxElement(array, 0, array.length);
	}

	public static int maxElement(int[] array, int from, int to) {
		int result = Integer.MIN_VALUE;
		for (int i = from; i < to; i++)
			result = Math.max(result, array[i]);
		return result;
	}

	public static int[] reversePermutation(int[] permutation) {
		int[] result = new int[permutation.length];
		for (int i = 0; i < permutation.length; i++)
			result[permutation[i]] = i;
		return result;
	}

	public static void reverse(int[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			int temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	public static void reverse(char[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			char temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	public static int minPosition(int[] array) {
		return minPosition(array, 0, array.length);
	}

	public static int maxPosition(int[] array) {
		return maxPosition(array, 0, array.length);
	}

	public static int minPosition(int[] array, int from, int to) {
		if (from >= to)
			return -1;
		int min = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] < min) {
				min = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int maxPosition(int[] array, int from, int to) {
		if (from >= to)
			return -1;
		int max = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] > max) {
				max = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int[] multiplyPermutations(int[] first, int[] second) {
		int count = first.length;
		int[] result = new int[count];
		for (int i = 0; i < count; i++) {
			result[i] = first[second[i]];
		}
		return result;
	}

	public static int[] compress(int[]... arrays) {
		int totalLength = 0;
		for (int[] array : arrays)
			totalLength += array.length;
		int[] all = new int[totalLength];
		int delta = 0;
		for (int[] array : arrays) {
			System.arraycopy(array, 0, all, delta, array.length);
			delta += array.length;
		}
		sort(all, IntComparator.DEFAULT);
		all = unique(all);
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i] = Arrays.binarySearch(all, array[i]);
		}
		return all;
	}

	public static int minElement(int[] array) {
		return array[minPosition(array)];
	}

	public static long[] partialSums(int[] array) {
		long[] result = new long[array.length + 1];
		for (int i = 0; i < array.length; i++)
			result[i + 1] = result[i] + array[i];
		return result;
	}

	public static long[] asLong(int[] array) {
		long[] result = new long[array.length];
		for (int i = 0; i < array.length; i++)
			result[i] = array[i];
		return result;
	}

	public static int count(int[] array, int value) {
		int result = 0;
		for (int i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int count(char[] array, char value) {
		int result = 0;
		for (char i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int count(boolean[] array, boolean value) {
		int result = 0;
		for (boolean i : array) {
			if (i == value)
				result++;
		}
		return result;
	}

	public static int[] merge(int[] first, int[] second) {
		int[] result = new int[first.length + second.length];
		int firstIndex = 0;
		int secondIndex = 0;
		int index = 0;
		while (firstIndex < first.length && secondIndex < second.length) {
			if (first[firstIndex] < second[secondIndex])
				result[index++] = first[firstIndex++];
			else
				result[index++] = second[secondIndex++];
		}
		System.arraycopy(first, firstIndex, result, index, first.length
				- firstIndex);
		System.arraycopy(second, secondIndex, result, index, second.length
				- secondIndex);
		return result;
	}

	public static boolean nextPermutation(int[] array) {
		return new IntArray(array).nextPermutation();
	}

	public static <V> void reverse(V[] array) {
		for (int i = 0, j = array.length - 1; i < j; i++, j--) {
			V temp = array[i];
			array[i] = array[j];
			array[j] = temp;
		}
	}

	public static IntComparator compareBy(final int[]... arrays) {
		return new IntComparator() {
			public int compare(int first, int second) {
				for (int[] array : arrays) {
					if (array[first] != array[second])
						return Integer.compare(array[first], array[second]);
				}
				return 0;
			}
		};
	}

	public static long minElement(long[] array) {
		return array[minPosition(array)];
	}

	public static long maxElement(long[] array) {
		return array[maxPosition(array)];
	}

	public static int minPosition(long[] array) {
		return minPosition(array, 0, array.length);
	}

	public static int maxPosition(long[] array) {
		return maxPosition(array, 0, array.length);
	}

	public static int minPosition(long[] array, int from, int to) {
		if (from >= to)
			return -1;
		long min = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] < min) {
				min = array[i];
				result = i;
			}
		}
		return result;
	}

	public static int maxPosition(long[] array, int from, int to) {
		if (from >= to)
			return -1;
		long max = array[from];
		int result = from;
		for (int i = from + 1; i < to; i++) {
			if (array[i] > max) {
				max = array[i];
				result = i;
			}
		}
		return result;
	}
}

class BidirectionalGraph extends Graph {
	public int[] transposedEdge;

	public BidirectionalGraph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public BidirectionalGraph(int vertexCount, int edgeCapacity) {
		super(vertexCount, 2 * edgeCapacity);
		transposedEdge = new int[2 * edgeCapacity];
	}

	public static BidirectionalGraph createGraph(int vertexCount, int[] from,
			int[] to) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static BidirectionalGraph createWeightedGraph(int vertexCount,
			int[] from, int[] to, long[] weight) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static BidirectionalGraph createFlowGraph(int vertexCount,
			int[] from, int[] to, long[] capacity) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static BidirectionalGraph createFlowWeightedGraph(int vertexCount,
			int[] from, int[] to, long[] weight, long[] capacity) {
		BidirectionalGraph graph = new BidirectionalGraph(vertexCount,
				from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	@Override
	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		int lastEdgeCount = edgeCount;
		super.addEdge(fromID, toID, weight, capacity, reverseEdge);
		super.addEdge(toID, fromID, weight, capacity, reverseEdge == -1 ? -1
				: reverseEdge + 1);
		this.transposedEdge[lastEdgeCount] = lastEdgeCount + 1;
		this.transposedEdge[lastEdgeCount + 1] = lastEdgeCount;
		return lastEdgeCount;
	}

	@Override
	protected int entriesPerEdge() {
		return 2;
	}

	@Override
	public final int transposed(int id) {
		return transposedEdge[id];
	}

	@Override
	protected void ensureEdgeCapacity(int size) {
		if (size > edgeCapacity()) {
			super.ensureEdgeCapacity(size);
			transposedEdge = resize(transposedEdge, edgeCapacity());
		}
	}
}

class Graph {
	public static final int REMOVED_BIT = 0;

	protected int vertexCount;
	protected int edgeCount;

	private int[] firstOutbound;
	private int[] firstInbound;

	private Edge[] edges;
	private int[] nextInbound;
	private int[] nextOutbound;
	private int[] from;
	private int[] to;
	private long[] weight;
	private long[] capacity;
	private int[] reverseEdge;
	private int[] flags;

	public Graph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public Graph(int vertexCount, int edgeCapacity) {
		this.vertexCount = vertexCount;
		firstOutbound = new int[vertexCount];
		Arrays.fill(firstOutbound, -1);

		from = new int[edgeCapacity];
		to = new int[edgeCapacity];
		nextOutbound = new int[edgeCapacity];
		flags = new int[edgeCapacity];
	}

	public static Graph createGraph(int vertexCount, int[] from, int[] to) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static Graph createWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static Graph createFlowGraph(int vertexCount, int[] from, int[] to,
			long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static Graph createFlowWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight, long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	public static Graph createTree(int[] parent) {
		Graph graph = new Graph(parent.length + 1, parent.length);
		for (int i = 0; i < parent.length; i++)
			graph.addSimpleEdge(parent[i], i + 1);
		return graph;
	}

	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		ensureEdgeCapacity(edgeCount + 1);
		if (firstOutbound[fromID] != -1)
			nextOutbound[edgeCount] = firstOutbound[fromID];
		else
			nextOutbound[edgeCount] = -1;
		firstOutbound[fromID] = edgeCount;
		if (firstInbound != null) {
			if (firstInbound[toID] != -1)
				nextInbound[edgeCount] = firstInbound[toID];
			else
				nextInbound[edgeCount] = -1;
			firstInbound[toID] = edgeCount;
		}
		this.from[edgeCount] = fromID;
		this.to[edgeCount] = toID;
		if (capacity != 0) {
			if (this.capacity == null)
				this.capacity = new long[from.length];
			this.capacity[edgeCount] = capacity;
		}
		if (weight != 0) {
			if (this.weight == null)
				this.weight = new long[from.length];
			this.weight[edgeCount] = weight;
		}
		if (reverseEdge != -1) {
			if (this.reverseEdge == null) {
				this.reverseEdge = new int[from.length];
				Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
			}
			this.reverseEdge[edgeCount] = reverseEdge;
		}
		if (edges != null)
			edges[edgeCount] = createEdge(edgeCount);
		return edgeCount++;
	}

	protected final GraphEdge createEdge(int id) {
		return new GraphEdge(id);
	}

	public final int addFlowWeightedEdge(int from, int to, long weight,
			long capacity) {
		if (capacity == 0) {
			return addEdge(from, to, weight, 0, -1);
		} else {
			int lastEdgeCount = edgeCount;
			addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
			return addEdge(from, to, weight, capacity, lastEdgeCount);
		}
	}

	protected int entriesPerEdge() {
		return 1;
	}

	public final int addFlowEdge(int from, int to, long capacity) {
		return addFlowWeightedEdge(from, to, 0, capacity);
	}

	public final int addWeightedEdge(int from, int to, long weight) {
		return addFlowWeightedEdge(from, to, weight, 0);
	}

	public final int addSimpleEdge(int from, int to) {
		return addWeightedEdge(from, to, 0);
	}

	public final int vertexCount() {
		return vertexCount;
	}

	public final int edgeCount() {
		return edgeCount;
	}

	protected final int edgeCapacity() {
		return from.length;
	}

	public final Edge edge(int id) {
		initEdges();
		return edges[id];
	}

	public final int firstOutbound(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int nextOutbound(int id) {
		id = nextOutbound[id];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int firstInbound(int vertex) {
		initInbound();
		int id = firstInbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int nextInbound(int id) {
		initInbound();
		id = nextInbound[id];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int source(int id) {
		return from[id];
	}

	public final int destination(int id) {
		return to[id];
	}

	public final long weight(int id) {
		if (weight == null)
			return 0;
		return weight[id];
	}

	public final long capacity(int id) {
		if (capacity == null)
			return 0;
		return capacity[id];
	}

	public final long flow(int id) {
		if (reverseEdge == null)
			return 0;
		return capacity[reverseEdge[id]];
	}

	public final void pushFlow(int id, long flow) {
		if (flow == 0)
			return;
		if (flow > 0) {
			if (capacity(id) < flow)
				throw new IllegalArgumentException("Not enough capacity");
		} else {
			if (flow(id) < -flow)
				throw new IllegalArgumentException("Not enough capacity");
		}
		capacity[id] -= flow;
		capacity[reverseEdge[id]] += flow;
	}

	public int transposed(int id) {
		return -1;
	}

	public final int reverse(int id) {
		if (reverseEdge == null)
			return -1;
		return reverseEdge[id];
	}

	public final void addVertices(int count) {
		ensureVertexCapacity(vertexCount + count);
		Arrays.fill(firstOutbound, vertexCount, vertexCount + count, -1);
		if (firstInbound != null)
			Arrays.fill(firstInbound, vertexCount, vertexCount + count, -1);
		vertexCount += count;
	}

	protected final void initEdges() {
		if (edges == null) {
			edges = new Edge[from.length];
			for (int i = 0; i < edgeCount; i++)
				edges[i] = createEdge(i);
		}
	}

	public final void removeVertex(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextOutbound[id];
		}
		initInbound();
		id = firstInbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextInbound[id];
		}
	}

	private void initInbound() {
		if (firstInbound == null) {
			firstInbound = new int[firstOutbound.length];
			Arrays.fill(firstInbound, 0, vertexCount, -1);
			nextInbound = new int[from.length];
			for (int i = 0; i < edgeCount; i++) {
				nextInbound[i] = firstInbound[to[i]];
				firstInbound[to[i]] = i;
			}
		}
	}

	public final boolean flag(int id, int bit) {
		return (flags[id] >> bit & 1) != 0;
	}

	public final void setFlag(int id, int bit) {
		flags[id] |= 1 << bit;
	}

	public final void removeFlag(int id, int bit) {
		flags[id] &= -1 - (1 << bit);
	}

	public final void removeEdge(int id) {
		setFlag(id, REMOVED_BIT);
	}

	public final void restoreEdge(int id) {
		removeFlag(id, REMOVED_BIT);
	}

	public final boolean isRemoved(int id) {
		return flag(id, REMOVED_BIT);
	}

	public final Iterable<Edge> outbound(final int id) {
		initEdges();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstOutbound, nextOutbound);
			}
		};
	}

	public final Iterable<Edge> inbound(final int id) {
		initEdges();
		initInbound();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstInbound, nextInbound);
			}
		};
	}

	protected void ensureEdgeCapacity(int size) {
		if (from.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			if (edges != null)
				edges = resize(edges, newSize);
			from = resize(from, newSize);
			to = resize(to, newSize);
			nextOutbound = resize(nextOutbound, newSize);
			if (nextInbound != null)
				nextInbound = resize(nextInbound, newSize);
			if (weight != null)
				weight = resize(weight, newSize);
			if (capacity != null)
				capacity = resize(capacity, newSize);
			if (reverseEdge != null)
				reverseEdge = resize(reverseEdge, newSize);
			flags = resize(flags, newSize);
		}
	}

	private void ensureVertexCapacity(int size) {
		if (firstOutbound.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			firstOutbound = resize(firstOutbound, newSize);
			if (firstInbound != null)
				firstInbound = resize(firstInbound, newSize);
		}
	}

	protected final int[] resize(int[] array, int size) {
		int[] newArray = new int[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private long[] resize(long[] array, int size) {
		long[] newArray = new long[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private Edge[] resize(Edge[] array, int size) {
		Edge[] newArray = new Edge[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	public final boolean isSparse() {
		return vertexCount == 0 || edgeCount * 20 / vertexCount <= vertexCount;
	}

	protected class GraphEdge implements Edge {
		protected int id;

		protected GraphEdge(int id) {
			this.id = id;
		}

		public int getSource() {
			return source(id);
		}

		public int getDestination() {
			return destination(id);
		}

		public long getWeight() {
			return weight(id);
		}

		public long getCapacity() {
			return capacity(id);
		}

		public long getFlow() {
			return flow(id);
		}

		public void pushFlow(long flow) {
			Graph.this.pushFlow(id, flow);
		}

		public boolean getFlag(int bit) {
			return flag(id, bit);
		}

		public void setFlag(int bit) {
			Graph.this.setFlag(id, bit);
		}

		public void removeFlag(int bit) {
			Graph.this.removeFlag(id, bit);
		}

		public int getTransposedID() {
			return transposed(id);
		}

		public Edge getTransposedEdge() {
			int reverseID = getTransposedID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getReverseID() {
			return reverse(id);
		}

		public Edge getReverseEdge() {
			int reverseID = getReverseID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getID() {
			return id;
		}

		public void remove() {
			removeEdge(id);
		}

		public void restore() {
			restoreEdge(id);
		}
	}

	public class EdgeIterator implements Iterator<Edge> {
		private int edgeID;
		private final int[] next;
		private int lastID = -1;

		public EdgeIterator(int id, int[] first, int[] next) {
			this.next = next;
			edgeID = nextEdge(first[id]);
		}

		private int nextEdge(int id) {
			while (id != -1 && isRemoved(id))
				id = next[id];
			return id;
		}

		public boolean hasNext() {
			return edgeID != -1;
		}

		public Edge next() {
			if (edgeID == -1)
				throw new NoSuchElementException();
			lastID = edgeID;
			edgeID = nextEdge(next[lastID]);
			return edges[lastID];
		}

		public void remove() {
			if (lastID == -1)
				throw new IllegalStateException();
			removeEdge(lastID);
			lastID = -1;
		}
	}

}

interface Function<A, V> {
	public abstract V value(A argument);
}

class MiscUtils {
	public static final int[] DX4 = { 1, 0, -1, 0 };
	public static final int[] DY4 = { 0, -1, 0, 1 };
	public static final int[] DX8 = { 1, 1, 1, 0, -1, -1, -1, 0 };
	public static final int[] DY8 = { -1, 0, 1, 1, 1, 0, -1, -1 };
	public static final int[] DX_KNIGHT = { 2, 1, -1, -2, -2, -1, 1, 2 };
	public static final int[] DY_KNIGHT = { 1, 2, 2, 1, -1, -2, -2, -1 };

	private static final String[] ROMAN_TOKENS = { "M", "CM", "D", "CD", "C",
			"XC", "L", "XL", "X", "IX", "V", "IV", "I" };
	private static final int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90,
			50, 40, 10, 9, 5, 4, 1 };

	public static long josephProblem(long n, int k) {
		if (n == 1)
			return 0;
		if (k == 1)
			return n - 1;
		if (k > n)
			return (josephProblem(n - 1, k) + k) % n;
		long count = n / k;
		long result = josephProblem(n - count, k);
		result -= n % k;
		if (result < 0)
			result += n;
		else
			result += result / (k - 1);
		return result;
	}

	public static boolean isValidCell(int row, int column, int rowCount,
			int columnCount) {
		return row >= 0 && row < rowCount && column >= 0
				&& column < columnCount;
	}

	public static IntList getPath(int[] last, int destination) {
		IntList path = new IntArrayList();
		while (destination != -1) {
			path.add(destination);
			destination = last[destination];
		}
		path.inPlaceReverse();
		return path;
	}

	public static IntList getPath(int[][] lastIndex, int[][] lastPathNumber,
			int destination, int pathNumber) {
		IntList path = new IntArrayList();
		while (destination != -1 || pathNumber != 0) {
			path.add(destination);
			int nextDestination = lastIndex[destination][pathNumber];
			pathNumber = lastPathNumber[destination][pathNumber];
			destination = nextDestination;
		}
		path.inPlaceReverse();
		return path;
	}

	public static long maximalRectangleSum(long[][] array) {
		int n = array.length;
		int m = array[0].length;
		long[][] partialSums = new long[n + 1][m + 1];
		for (int i = 0; i < n; i++) {
			long rowSum = 0;
			for (int j = 0; j < m; j++) {
				rowSum += array[i][j];
				partialSums[i + 1][j + 1] = partialSums[i][j + 1] + rowSum;
			}
		}
		long result = Long.MIN_VALUE;
		for (int i = 0; i < m; i++) {
			for (int j = i; j < m; j++) {
				long minPartialSum = 0;
				for (int k = 1; k <= n; k++) {
					long current = partialSums[k][j + 1] - partialSums[k][i];
					result = Math.max(result, current - minPartialSum);
					minPartialSum = Math.min(minPartialSum, current);
				}
			}
		}
		return result;
	}

	public static int parseIP(String ip) {
		String[] components = ip.split("[.]");
		int result = 0;
		for (int i = 0; i < 4; i++)
			result += (1 << (24 - 8 * i)) * Integer.parseInt(components[i]);
		return result;
	}

	public static String buildIP(int mask) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			if (i != 0)
				result.append('.');
			result.append(mask >> (24 - 8 * i) & 255);
		}
		return result.toString();
	}

	public static long binarySearch(long from, long to,
			Function<Long, Boolean> function) {
		while (from < to) {
			long argument = from + (to - from) / 2;
			if (function.value(argument))
				to = argument;
			else
				from = argument + 1;
		}
		return from;
	}

	public static <T> boolean equals(T first, T second) {
		return first == null && second == null || first != null
				&& first.equals(second);
	}

	public static boolean isVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'
				|| ch == 'Y';
	}

	public static boolean isStrictVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
	}

	public static String convertToRoman(int number) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number >= ROMAN_VALUES[i]) {
				number -= ROMAN_VALUES[i];
				result.append(ROMAN_TOKENS[i]);
			}
		}
		return result.toString();
	}

	public static int convertFromRoman(String number) {
		int result = 0;
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number.startsWith(ROMAN_TOKENS[i])) {
				number = number.substring(ROMAN_TOKENS[i].length());
				result += ROMAN_VALUES[i];
			}
		}
		return result;
	}

	public static int distance(int x1, int y1, int x2, int y2) {
		int dx = x1 - x2;
		int dy = y1 - y2;
		return dx * dx + dy * dy;
	}

	public static <T extends Comparable<T>> T min(T first, T second) {
		if (first.compareTo(second) <= 0)
			return first;
		return second;
	}

	public static <T extends Comparable<T>> T max(T first, T second) {
		if (first.compareTo(second) <= 0)
			return second;
		return first;
	}

	public static void decreaseByOne(int[]... arrays) {
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i]--;
		}
	}

	public static int[] getIntArray(String s) {
		String[] tokens = s.split(" ");
		int[] result = new int[tokens.length];
		for (int i = 0; i < result.length; i++)
			result[i] = Integer.parseInt(tokens[i]);
		return result;
	}
}

interface Edge {
	public int getSource();

	public int getDestination();

	public long getWeight();

	public long getCapacity();

	public long getFlow();

	public void pushFlow(long flow);

	public boolean getFlag(int bit);

	public void setFlag(int bit);

	public void removeFlag(int bit);

	public int getTransposedID();

	public Edge getTransposedEdge();

	public int getReverseID();

	public Edge getReverseEdge();

	public int getID();

	public void remove();

	public void restore();
}

class IntArrayList extends IntList {
	private int[] array;
	private int size;

	public IntArrayList() {
		this(10);
	}

	public IntArrayList(int capacity) {
		array = new int[capacity];
	}

	public IntArrayList(IntList list) {
		this(list.size());
		addAll(list);
	}

	@Override
	public int get(int index) {
		if (index >= size)
			throw new IndexOutOfBoundsException();
		return array[index];
	}

	@Override
	public void set(int index, int value) {
		if (index >= size)
			throw new IndexOutOfBoundsException();
		array[index] = value;
	}

	@Override
	public int size() {
		return size;
	}

	@Override
	public void add(int value) {
		ensureCapacity(size + 1);
		array[size++] = value;
	}

	public void ensureCapacity(int newCapacity) {
		if (newCapacity > array.length) {
			int[] newArray = new int[Math.max(newCapacity, array.length << 1)];
			System.arraycopy(array, 0, newArray, 0, size);
			array = newArray;
		}
	}

	@Override
	public int[] toArray() {
		int[] array = new int[size];
		System.arraycopy(this.array, 0, array, 0, size);
		return array;
	}

	@Override
	public int popBack() {
		return array[--size];
	}
}

class IntArray extends IntList {
	private final int[] array;

	public IntArray(int[] array) {
		this.array = array;
	}

	public IntArray(IntCollection collection) {
		array = new int[collection.size()];
		int i = 0;
		for (IntIterator iterator = collection.iterator(); iterator.isValid(); iterator
				.advance())
			array[i++] = iterator.value();
	}

	@Override
	public int get(int index) {
		return array[index];
	}

	@Override
	public void set(int index, int value) {
		array[index] = value;
	}

	@Override
	public int size() {
		return array.length;
	}

	@Override
	public void add(int value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public int[] toArray() {
		return array;
	}
}

abstract class IntList extends IntCollection implements Comparable<IntList> {
	private static final int INSERTION_THRESHOLD = 16;
	private static IntList EMPTY_LIST;

	public abstract int get(int index);

	public abstract void set(int index, int value);

	@Override
	public IntIterator iterator() {
		return new IntIterator() {
			private int size = size();
			private int index = 0;

			public int value() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				return get(index);
			}

			public void advance() throws NoSuchElementException {
				if (!isValid())
					throw new NoSuchElementException();
				index++;
			}

			public boolean isValid() {
				return index < size;
			}
		};
	}

	@Override
	public void remove(int value) {
		throw new UnsupportedOperationException();
	}

	public int find(int value) {
		int size = size();
		for (int i = 0; i < size; i++) {
			if (get(i) == value)
				return i;
		}
		return -1;
	}

	public int findLast(int value) {
		int size = size();
		for (int i = size - 1; i >= 0; i--) {
			if (get(i) == value)
				return i;
		}
		return -1;
	}

	public boolean nextPermutation() {
		return nextPermutation(IntComparator.DEFAULT);
	}

	private boolean nextPermutation(IntComparator comparator) {
		int size = size();
		int last = get(size - 1);
		for (int i = size - 2; i >= 0; i--) {
			int current = get(i);
			if (comparator.compare(last, current) > 0) {
				for (int j = size - 1; j > i; j--) {
					if (comparator.compare(get(j), current) > 0) {
						swap(i, j);
						subList(i + 1, size).inPlaceReverse();
						return true;
					}
				}
			}
			last = current;
		}
		return false;
	}

	public void inPlaceReverse() {
		for (int i = 0, j = size() - 1; i < j; i++, j--)
			swap(i, j);
	}

	public IntList subList(final int from, final int to) {
		return new SubList(from, to);
	}

	private void swap(int first, int second) {
		if (first == second)
			return;
		int temp = get(first);
		set(first, get(second));
		set(second, temp);
	}

	public IntSortedList inPlaceSort() {
		return inPlaceSort(IntComparator.DEFAULT);
	}

	public IntSortedList inPlaceSort(IntComparator comparator) {
		quickSort(0, size() - 1,
				(Integer.bitCount(Integer.highestOneBit(size()) - 1) * 5) >> 1,
				comparator);
		return new IntSortedArray(this, comparator);
	}

	private void quickSort(int from, int to, int remaining,
			IntComparator comparator) {
		if (to - from < INSERTION_THRESHOLD) {
			insertionSort(from, to, comparator);
			return;
		}
		if (remaining == 0) {
			heapSort(from, to, comparator);
			return;
		}
		remaining--;
		int pivotIndex = (from + to) >> 1;
		int pivot = get(pivotIndex);
		swap(pivotIndex, to);
		int storeIndex = from;
		int equalIndex = to;
		for (int i = from; i < equalIndex; i++) {
			int value = comparator.compare(get(i), pivot);
			if (value < 0)
				swap(storeIndex++, i);
			else if (value == 0)
				swap(--equalIndex, i--);
		}
		quickSort(from, storeIndex - 1, remaining, comparator);
		for (int i = equalIndex; i <= to; i++)
			swap(storeIndex++, i);
		quickSort(storeIndex, to, remaining, comparator);
	}

	private void heapSort(int from, int to, IntComparator comparator) {
		for (int i = (to + from - 1) >> 1; i >= from; i--)
			siftDown(i, to, comparator, from);
		for (int i = to; i > from; i--) {
			swap(from, i);
			siftDown(from, i - 1, comparator, from);
		}
	}

	private void siftDown(int start, int end, IntComparator comparator,
			int delta) {
		int value = get(start);
		while (true) {
			int child = ((start - delta) << 1) + 1 + delta;
			if (child > end)
				return;
			int childValue = get(child);
			if (child + 1 <= end) {
				int otherValue = get(child + 1);
				if (comparator.compare(otherValue, childValue) > 0) {
					child++;
					childValue = otherValue;
				}
			}
			if (comparator.compare(value, childValue) >= 0)
				return;
			swap(start, child);
			start = child;
		}
	}

	private void insertionSort(int from, int to, IntComparator comparator) {
		for (int i = from + 1; i <= to; i++) {
			int value = get(i);
			for (int j = i - 1; j >= from; j--) {
				if (comparator.compare(get(j), value) <= 0)
					break;
				swap(j, j + 1);
			}
		}
	}

	public IntSortedList sort() {
		return sort(IntComparator.DEFAULT);
	}

	public IntSortedList sort(IntComparator comparator) {
		return new IntArray(this).inPlaceSort(comparator);
	}

	public int back() {
		return get(size() - 1);
	}

	public int popBack() {
		throw new UnsupportedOperationException();
	}

	public int hashCode() {
		int hashCode = 1;
		for (IntIterator i = iterator(); i.isValid(); i.advance())
			hashCode = 31 * hashCode + i.value();
		return hashCode;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof IntList))
			return false;
		IntList list = (IntList) obj;
		if (list.size() != size())
			return false;
		IntIterator i = iterator();
		IntIterator j = list.iterator();
		while (i.isValid()) {
			if (i.value() != j.value())
				return false;
			i.advance();
			j.advance();
		}
		return true;
	}

	public int compareTo(IntList o) {
		IntIterator i = iterator();
		IntIterator j = o.iterator();
		while (true) {
			if (i.isValid()) {
				if (j.isValid()) {
					if (i.value() != j.value()) {
						if (i.value() < j.value())
							return -1;
						else
							return 1;
					}
				} else
					return 1;
			} else {
				if (j.isValid())
					return -1;
				else
					return 0;
			}
			i.advance();
			j.advance();
		}
	}

	public static IntList emptyList() {
		if (EMPTY_LIST == null)
			EMPTY_LIST = new IntArray(new int[0]);
		return EMPTY_LIST;
	}

	private class SubList extends IntList {
		private final int to;
		private final int from;
		private int size;

		public SubList(int from, int to) {
			this.to = to;
			this.from = from;
			size = to - from;
		}

		@Override
		public int get(int index) {
			if (index < 0 || index >= size)
				throw new IndexOutOfBoundsException();
			return IntList.this.get(index + from);
		}

		@Override
		public void set(int index, int value) {
			if (index < 0 || index >= size)
				throw new IndexOutOfBoundsException();
			IntList.this.set(index + from, value);
		}

		@Override
		public int size() {
			return size;
		}

		@Override
		public void add(int value) {
			throw new UnsupportedOperationException();
		}
	}
}

abstract class IntCollection {
	public abstract IntIterator iterator();

	public abstract int size();

	public abstract void add(int value);

	public abstract void remove(int value);

	public void forEach(IntTask task) {
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance())
			task.process(iterator.value());
	}

	public boolean contains(int value) {
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance()) {
			if (iterator.value() == value)
				return true;
		}
		return false;
	}

	public int count(int value) {
		int result = 0;
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance()) {
			if (iterator.value() == value)
				result++;
		}
		return result;
	}

	public int min() {
		if (size() == 0)
			throw new NoSuchElementException();
		int result = Integer.MAX_VALUE;
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance())
			result = Math.min(result, iterator.value());
		return result;
	}

	public int max() {
		if (size() == 0)
			throw new NoSuchElementException();
		int result = Integer.MIN_VALUE;
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance())
			result = Math.max(result, iterator.value());
		return result;
	}

	public IntCollection union(final IntCollection other) {
		return new IntCollection() {
			@Override
			public IntIterator iterator() {
				return new IntIterator() {
					private IntIterator first = IntCollection.this.iterator();
					private IntIterator second;

					public int value() throws NoSuchElementException {
						if (first.isValid())
							return first.value();
						return second.value();
					}

					public void advance() throws NoSuchElementException {
						if (first.isValid()) {
							first.advance();
							if (!first.isValid())
								second = other.iterator();
						} else
							second.advance();
					}

					public boolean isValid() {
						return first.isValid() || second.isValid();
					}
				};
			}

			@Override
			public int size() {
				return IntCollection.this.size() + other.size();
			}

			@Override
			public void add(int value) {
				throw new UnsupportedOperationException();
			}

			@Override
			public void remove(int value) {
				throw new UnsupportedOperationException();
			}
		};
	}

	public IntCollection map(final IntFunction function) {
		return new IntCollection() {
			@Override
			public IntIterator iterator() {
				return new IntIterator() {
					private IntIterator iterator = IntCollection.this
							.iterator();

					public int value() throws NoSuchElementException {
						return function.value(iterator.value());
					}

					public void advance() throws NoSuchElementException {
						iterator().advance();
					}

					public boolean isValid() {
						return iterator().isValid();
					}
				};
			}

			@Override
			public int size() {
				return IntCollection.this.size();
			}

			@Override
			public void add(int value) {
				throw new UnsupportedOperationException();
			}

			@Override
			public void remove(int value) {
				throw new UnsupportedOperationException();
			}
		};
	}

	public int[] toArray() {
		int size = size();
		int[] array = new int[size];
		int i = 0;
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance())
			array[i++] = iterator.value();
		return array;
	}

	public long sum() {
		long result = 0;
		for (IntIterator iterator = iterator(); iterator.isValid(); iterator
				.advance())
			result += iterator.value();
		return result;
	}

	public void addAll(IntCollection values) {
		for (IntIterator it = values.iterator(); it.isValid(); it.advance()) {
			add(it.value());
		}
	}

	public void removeAll(IntCollection values) {
		for (IntIterator it = values.iterator(); it.isValid(); it.advance()) {
			remove(it.value());
		}
	}

	public void retainAll(IntCollection values) {
		for (IntIterator it = iterator(); it.isValid(); it.advance()) {
			if (!values.contains(it.value())) {
				remove(it.value());
			}
		}
	}
}

interface IntIterator {
	public int value() throws NoSuchElementException;

	/*
	 * @throws NoSuchElementException only if iterator already invalid
	 */
	public void advance() throws NoSuchElementException;

	public boolean isValid();
}

abstract class IntSortedList extends IntList {
	protected final IntComparator comparator;

	protected IntSortedList(IntComparator comparator) {
		this.comparator = comparator;
	}

	@Override
	public void set(int index, int value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void add(int value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public IntSortedList inPlaceSort(IntComparator comparator) {
		if (comparator == this.comparator)
			return this;
		throw new UnsupportedOperationException();
	}

	@Override
	public boolean contains(int value) {
		int index = lowerBound(value);
		return index != size() && get(index) == value;
	}

	public int lowerBound(int value) {
		int left = 0;
		int right = size();
		while (left < right) {
			int middle = (left + right) >> 1;
			if (comparator.compare(get(middle), value) >= 0)
				right = middle;
			else
				left = middle + 1;
		}
		return left;
	}

	public int upperBound(int value) {
		int left = 0;
		int right = size();
		while (left < right) {
			int middle = (left + right) >> 1;
			if (comparator.compare(get(middle), value) > 0)
				right = middle;
			else
				left = middle + 1;
		}
		return left;
	}

	protected void ensureSorted() {
		int size = size();
		if (size == 0)
			return;
		int last = get(0);
		for (int i = 1; i < size; i++) {
			int current = get(i);
			if (comparator.compare(last, current) > 0)
				throw new IllegalArgumentException();
			last = current;
		}
	}

	@Override
	public IntSortedList subList(final int from, final int to) {
		return new IntSortedList(comparator) {
			private int size = to - from;

			@Override
			public int get(int index) {
				if (index < 0 || index >= size)
					throw new IndexOutOfBoundsException();
				return IntSortedList.this.get(index + from);
			}

			@Override
			public int size() {
				return size;
			}
		};
	}
}

class IntSortedArray extends IntSortedList {
	private final int[] array;

	public IntSortedArray(int[] array) {
		this(array, IntComparator.DEFAULT);
	}

	public IntSortedArray(IntCollection collection) {
		this(collection, IntComparator.DEFAULT);
	}

	public IntSortedArray(int[] array, IntComparator comparator) {
		super(comparator);
		this.array = array;
		ensureSorted();
	}

	public IntSortedArray(IntCollection collection, IntComparator comparator) {
		super(comparator);
		array = new int[collection.size()];
		int i = 0;
		for (IntIterator iterator = collection.iterator(); iterator.isValid(); iterator
				.advance())
			array[i++] = iterator.value();
		ensureSorted();
	}

	@Override
	public int get(int index) {
		return array[index];
	}

	@Override
	public int size() {
		return array.length;
	}
}

interface IntComparator {
	public static final IntComparator DEFAULT = new IntComparator() {
		public int compare(int first, int second) {
			if (first < second)
				return -1;
			if (first > second)
				return 1;
			return 0;
		}
	};

	public static final IntComparator REVERSE = new IntComparator() {
		public int compare(int first, int second) {
			if (first < second)
				return 1;
			if (first > second)
				return -1;
			return 0;
		}
	};

	public int compare(int first, int second);
}

interface IntTask {
	public void process(int value);
}

interface IntFunction {
	public int value(int key);
}

class IntegerUtils {
	public static long gcd(long a, long b) {
		a = Math.abs(a);
		b = Math.abs(b);
		while (b != 0) {
			long temp = a % b;
			a = b;
			b = temp;
		}
		return a;
	}

	public static int gcd(int a, int b) {
		a = Math.abs(a);
		b = Math.abs(b);
		while (b != 0) {
			int temp = a % b;
			a = b;
			b = temp;
		}
		return a;
	}

	public static int[] generatePrimes(int upTo) {
		int[] isPrime = generateBitPrimalityTable(upTo);
		IntList primes = new IntArrayList();
		for (int i = 0; i < upTo; i++) {
			if ((isPrime[i >> 5] >>> (i & 31) & 1) == 1)
				primes.add(i);
		}
		return primes.toArray();
	}

	public static boolean[] generatePrimalityTable(int upTo) {
		boolean[] isPrime = new boolean[upTo];
		if (upTo < 2)
			return isPrime;
		Arrays.fill(isPrime, true);
		isPrime[0] = isPrime[1] = false;
		for (int i = 2; i * i < upTo; i++) {
			if (isPrime[i]) {
				for (int j = i * i; j < upTo; j += i)
					isPrime[j] = false;
			}
		}
		return isPrime;
	}

	public static int[] generateBitPrimalityTable(int upTo) {
		int[] isPrime = new int[(upTo + 31) >> 5];
		if (upTo < 2)
			return isPrime;
		Arrays.fill(isPrime, -1);
		isPrime[0] &= -4;
		for (int i = 2; i * i < upTo; i++) {
			if ((isPrime[i >> 5] >>> (i & 31) & 1) == 1) {
				for (int j = i * i; j < upTo; j += i)
					isPrime[j >> 5] &= -1 - (1 << (j & 31));
			}
		}
		return isPrime;
	}

	public static int[] generateDivisorTable(int upTo) {
		int[] divisor = new int[upTo];
		for (int i = 1; i < upTo; i++)
			divisor[i] = i;
		for (int i = 2; i * i < upTo; i++) {
			if (divisor[i] == i) {
				for (int j = i * i; j < upTo; j += i)
					divisor[j] = i;
			}
		}
		return divisor;
	}

	public static long powerInFactorial(long n, long p) {
		long result = 0;
		while (n != 0) {
			result += n /= p;
		}
		return result;
	}

	public static int sumDigits(CharSequence number) {
		int result = 0;
		for (int i = number.length() - 1; i >= 0; i--)
			result += digitValue(number.charAt(i));
		return result;
	}

	public static int digitValue(char digit) {
		if (Character.isDigit(digit))
			return digit - '0';
		if (Character.isUpperCase(digit))
			return digit + 10 - 'A';
		return digit + 10 - 'a';
	}

	public static int longCompare(long a, long b) {
		if (a < b)
			return -1;
		if (a > b)
			return 1;
		return 0;
	}

	public static long[][] generateBinomialCoefficients(int n) {
		long[][] result = new long[n + 1][n + 1];
		for (int i = 0; i <= n; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++)
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
		}
		return result;
	}

	public static long[][] generateBinomialCoefficients(int n, long module) {
		long[][] result = new long[n + 1][n + 1];
		if (module == 1)
			return result;
		for (int i = 0; i <= n; i++) {
			result[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
				if (result[i][j] >= module)
					result[i][j] -= module;
			}
		}
		return result;
	}

	public static long[] generateBinomialRow(int n, long module) {
		long[] result = generateReverse(n + 1, module);
		result[0] = 1;
		for (int i = 1; i <= n; i++)
			result[i] = result[i - 1] * (n - i + 1) % module * result[i]
					% module;
		return result;
	}

	public static int[] representationInBase(long number, int base) {
		long basePower = base;
		int exponent = 1;
		while (number >= basePower) {
			basePower *= base;
			exponent++;
		}
		int[] representation = new int[exponent];
		for (int i = 0; i < exponent; i++) {
			basePower /= base;
			representation[i] = (int) (number / basePower);
			number %= basePower;
		}
		return representation;
	}

	public static int trueDivide(int a, int b) {
		return (a - trueMod(a, b)) / b;
	}

	public static long trueDivide(long a, long b) {
		return (a - trueMod(a, b)) / b;
	}

	public static int trueMod(int a, int b) {
		a %= b;
		a += b;
		a %= b;
		return a;
	}

	public static long trueMod(long a, long b) {
		a %= b;
		a += b;
		a %= b;
		return a;
	}

	public static long factorial(int n) {
		long result = 1;
		for (int i = 2; i <= n; i++)
			result *= i;
		return result;
	}

	public static long factorial(int n, long mod) {
		long result = 1;
		for (int i = 2; i <= n; i++)
			result = result * i % mod;
		return result % mod;
	}

	public static List<Pair<Long, Integer>> factorize(long number) {
		List<Pair<Long, Integer>> result = new ArrayList<Pair<Long, Integer>>();
		for (long i = 2; i * i <= number; i++) {
			if (number % i == 0) {
				int power = 0;
				do {
					power++;
					number /= i;
				} while (number % i == 0);
				result.add(Pair.makePair(i, power));
			}
		}
		if (number != 1)
			result.add(Pair.makePair(number, 1));
		return result;
	}

	public static List<Long> getDivisors(long number) {
		List<Pair<Long, Integer>> primeDivisors = factorize(number);
		return getDivisorsImpl(primeDivisors, 0, 1, new ArrayList<Long>());
	}

	private static List<Long> getDivisorsImpl(
			List<Pair<Long, Integer>> primeDivisors, int index, long current,
			List<Long> result) {
		if (index == primeDivisors.size()) {
			result.add(current);
			return result;
		}
		long p = primeDivisors.get(index).first;
		int power = primeDivisors.get(index).second;
		for (int i = 0; i <= power; i++) {
			getDivisorsImpl(primeDivisors, index + 1, current, result);
			current *= p;
		}
		return result;
	}

	public static long power(long base, long exponent) {
		if (exponent == 0)
			return 1;
		long result = power(base, exponent >> 1);
		result = result * result;
		if ((exponent & 1) != 0)
			result = result * base;
		return result;
	}

	public static long power(long base, long exponent, long mod) {
		if (base >= mod)
			base %= mod;
		if (exponent == 0)
			return 1 % mod;
		long result = power(base, exponent >> 1, mod);
		result = result * result % mod;
		if ((exponent & 1) != 0)
			result = result * base % mod;
		return result;
	}

	public static long lcm(long a, long b) {
		return a / gcd(a, b) * b;
	}

	public static long[] generateFibonacci(long upTo) {
		int count = 0;
		long last = 0;
		long current = 1;
		while (current <= upTo) {
			long next = last + current;
			last = current;
			current = next;
			count++;
		}
		return generateFibonacci(count, -1);
	}

	public static long[] generateFibonacci(int count, long module) {
		long[] result = new long[count];
		if (module == -1) {
			if (count != 0)
				result[0] = 1;
			if (count > 1)
				result[1] = 1;
			for (int i = 2; i < count; i++)
				result[i] = result[i - 1] + result[i - 2];
		} else {
			if (count != 0)
				result[0] = 1 % module;
			if (count > 1)
				result[1] = 1 % module;
			for (int i = 2; i < count; i++)
				result[i] = (result[i - 1] + result[i - 2]) % module;
		}
		return result;
	}

	public static long[] generateHappy(int digits) {
		long[] happy = new long[(1 << (digits + 1)) - 2];
		happy[0] = 4;
		happy[1] = 7;
		int first = 0;
		int last = 2;
		for (int i = 2; i <= digits; i++) {
			for (int j = 0; j < last - first; j++) {
				happy[last + 2 * j] = 10 * happy[first + j] + 4;
				happy[last + 2 * j + 1] = 10 * happy[first + j] + 7;
			}
			int next = last + 2 * (last - first);
			first = last;
			last = next;
		}
		return happy;
	}

	public static long[] generateFactorial(int count, long module) {
		long[] result = new long[count];
		if (module == -1) {
			if (count != 0)
				result[0] = 1;
			for (int i = 1; i < count; i++)
				result[i] = result[i - 1] * i;
		} else {
			if (count != 0)
				result[0] = 1 % module;
			for (int i = 1; i < count; i++)
				result[i] = (result[i - 1] * i) % module;
		}
		return result;
	}

	public static long reverse(long number, long module) {
		return power(number, module - 2, module);
	}

	public static boolean isPrime(long number) {
		if (number < 2)
			return false;
		for (long i = 2; i * i <= number; i++) {
			if (number % i == 0)
				return false;
		}
		return true;
	}

	public static long[] generateReverse(int upTo, long module) {
		long[] result = new long[upTo];
		if (upTo > 1)
			result[1] = 1;
		for (int i = 2; i < upTo; i++)
			result[i] = (module - module / i * result[((int) (module % i))]
					% module)
					% module;
		return result;
	}

	public static long[] generateReverseFactorials(int upTo, long module) {
		long[] result = generateReverse(upTo, module);
		if (upTo > 0)
			result[0] = 1;
		for (int i = 1; i < upTo; i++)
			result[i] = result[i] * result[i - 1] % module;
		return result;
	}

	public static long[] generatePowers(long base, int count, long mod) {
		long[] result = new long[count];
		if (count != 0)
			result[0] = 1 % mod;
		for (int i = 1; i < count; i++)
			result[i] = result[i - 1] * base % mod;
		return result;
	}

	public static long nextPrime(long from) {
		if (from <= 2)
			return 2;
		from += 1 - (from & 1);
		while (!isPrime(from))
			from += 2;
		return from;
	}

	public static long binomialCoefficient(int n, int m, long mod) {
		if (m < 0 || m > n)
			return 0;
		if (2 * m > n)
			m = n - m;
		long result = 1;
		for (int i = n - m + 1; i <= n; i++)
			result = result * i % mod;
		return result
				* BigInteger.valueOf(factorial(m, mod))
						.modInverse(BigInteger.valueOf(mod)).longValue() % mod;
	}

	public static boolean isSquare(long number) {
		long sqrt = Math.round(Math.sqrt(number));
		return sqrt * sqrt == number;
	}

	public static long findCommon(long aRemainder, long aMod, long bRemainder,
			long bMod) {
		long modGCD = gcd(aMod, bMod);
		long gcdRemainder = aRemainder % modGCD;
		if (gcdRemainder != bRemainder % modGCD)
			return -1;
		aMod /= modGCD;
		aRemainder /= modGCD;
		bMod /= modGCD;
		bRemainder /= modGCD;
		long aReverse = BigInteger.valueOf(aMod)
				.modInverse(BigInteger.valueOf(bMod)).longValue();
		long bReverse = BigInteger.valueOf(bMod)
				.modInverse(BigInteger.valueOf(aMod)).longValue();
		long mod = aMod * bMod;
		return (bReverse * aRemainder % mod * bMod + aReverse * bRemainder
				% mod * aMod)
				% mod * modGCD + gcdRemainder;
	}

	public static long[] generatePowers(long base, long maxValue) {
		if (maxValue <= 0)
			return new long[0];
		int size = 1;
		long current = 1;
		while (maxValue / base >= current) {
			current *= base;
			size++;
		}
		return generatePowers(base, size, Long.MAX_VALUE);
	}
}

class Pair<U, V> implements Comparable<Pair<U, V>> {
	public final U first;
	public final V second;

	public static <U, V> Pair<U, V> makePair(U first, V second) {
		return new Pair<U, V>(first, second);
	}

	private Pair(U first, V second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Pair pair = (Pair) o;

		return !(first != null ? !first.equals(pair.first) : pair.first != null)
				&& !(second != null ? !second.equals(pair.second)
						: pair.second != null);

	}

	@Override
	public int hashCode() {
		int result = first != null ? first.hashCode() : 0;
		result = 31 * result + (second != null ? second.hashCode() : 0);
		return result;
	}

	public Pair<V, U> swap() {
		return makePair(second, first);
	}

	@Override
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	@SuppressWarnings({ "unchecked" })
	public int compareTo(Pair<U, V> o) {
		int value = ((Comparable<U>) first).compareTo(o.first);
		if (value != 0)
			return value;
		return ((Comparable<V>) second).compareTo(o.second);
	}
}

interface IndependentSetSystem {
	public boolean join(int first, int second);

	public int get(int index);

	public int getSetCount();

	public void setListener(Listener listener);

	public static interface Listener {
		public void joined(int joinedRoot, int root);
	}
}

class RecursiveIndependentSetSystem implements IndependentSetSystem {
	private final int[] color;
	private final int[] rank;
	private int setCount;
	private Listener listener;

	public RecursiveIndependentSetSystem(int size) {
		color = new int[size];
		rank = new int[size];
		for (int i = 0; i < size; i++)
			color[i] = i;
		setCount = size;
	}

	public RecursiveIndependentSetSystem(RecursiveIndependentSetSystem other) {
		color = other.color.clone();
		rank = other.rank.clone();
		setCount = other.setCount;
	}

	public boolean join(int first, int second) {
		first = get(first);
		second = get(second);
		if (first == second)
			return false;
		if (rank[first] < rank[second]) {
			int temp = first;
			first = second;
			second = temp;
		} else if (rank[first] == rank[second])
			rank[first]++;
		setCount--;
		color[second] = first;
		if (listener != null)
			listener.joined(second, first);
		return true;
	}

	public int get(int index) {
		if (color[index] == index)
			return index;
		return color[index] = get(color[index]);
	}

	public int getSetCount() {
		return setCount;
	}

	public void setListener(Listener listener) {
		this.listener = listener;
	}
}

import java.util.Scanner;

public class b {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
	int m=sc.nextInt();
	int a[]=new int [3];
	a[0]=m;
	int g=0;

	for(int i=1;i<3;i++)
	{
		a[i]=sc.nextInt();
		if(a[i]>m)
		{
			m=a[i];
		g=i;
	}
	}
	long s=0;
	for(int i=0;i<3;i++)
	{
		if(i==g)
		{

		}
		else
			s=s+a[i];
	}
	//System.out.println((m));

		if((2*s)<m)
		{
			System.out.println(s);
		}
		else
		{
			System.out.println((s+m)/3);
		}
	}
}

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

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author KHALED
 */
public class TableDecorations {
    public static void main(String[] args) {
        Scanner scan=new Scanner(System.in);
        long[]arr=new long[3];
        for (int i = 0; i < 3; i++) {
            arr[i]=scan.nextLong();
        }
        Arrays.sort(arr);
        if(2*arr[0]+2*arr[1]<=arr[2])
            System.out.println(arr[0]+arr[1]);
        else
            System.out.println((arr[0]+arr[1]+arr[2])/3);
    }
}

//table decorations
import java.util.*;
public class c {

    public static void main(String[] args){

        Scanner in = new Scanner(System.in);

        long[] a = new long[3];
        for(int i = 0; i < 3; i ++)a[i] = in.nextLong();
        Arrays.sort(a);
        a[2] = Math.min(2*(a[0] + a[1]), a[2]);
        long ans = (a[0] + a[1] + a[2]) / 3l;
        System.out.println(ans);
    }
}

import java.util.*;
public class marte{

private int contor=0;

public static void main (String args[]) {

Scanner input=new Scanner(System.in);

HashMap<Integer, Integer> map1= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> map2= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> finish= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> maxime= new HashMap<Integer, Integer>();

			Long r=input.nextLong();
			Long g=input.nextLong();
			Long b=input.nextLong();

			Long mese=0L;
			Long max=-1L;
			Long min=-1L;
			Long med=-1L;
			Long temp;

			if(r-g>=0L && r-b>=0L)

			{

			max=r;

			if(g-b>=0L) {med=g;min=b;}
			else {med=b;min=g;}

			}

			else if(g-r>=0L && g-b>=0L)

			{

			max=g;

			if(r-b>=0L) {med=r;min=b;}
			else {med=b;min=r;}

			}

			else if(b-r>=0L && b-g>=0L)

			{

			max=b;

			if(r-g>=0L) {med=r;min=g;}
			else {med=g;min=r;}

			}

		temp=(max+med+min)/3;
	Long sec=med+min;

	if(temp<sec) mese=temp;
	else mese=sec;

	System.out.println(mese);
	}

		}

import java.util.*;
public class Decoaration {
public static void main(String[] args){
	Scanner input = new Scanner(System.in);
	long r = input.nextLong();
	long g = input.nextLong();
	long b = input.nextLong();
	long table = (r + g + b) / 3;
	if(r== 0 && b == 0 && g == 0) System.out.println(0);
	else if(r == 0 && b != 0 && g != 0){
		if(b >= g){
			if(b % 2 == 0) System.out.println(Math.min(b / 2, g));
			else if(g <= b / 2) System.out.println(g);
			else if(g - b / 2 >= 2) System.out.println(b / 2 + 1);
		}
		else{
			if(g % 2 == 0) System.out.println(Math.min(g / 2, b));
			else if(b <= g / 2) System.out.println(b);
			else if(b - g / 2 >= 2) System.out.println(g / 2 + 1);
		}
	}
	else if (b == 0 && g != 0 && r != 0){
		if(g >= r){
			if(g % 2 == 0) System.out.println(Math.min(g / 2, r));
			else if(r <= g / 2) System.out.println(r);
			else if(r - g / 2 >= 2) System.out.println(g / 2 + 1);
		}
		else{
			if(r % 2 == 0) System.out.println(Math.min(r / 2, g));
			else if(g <= r / 2) System.out.println(g);
			else if(g - r / 2 >= 2) System.out.println(r / 2 + 1);
		}
	}
	else if(g == 0 && b != 0 && r != 0){
		if(b >= r){
			if(b % 2 == 0) System.out.println(Math.min(b / 2, r));
			else if(r <= b / 2) System.out.println(r);
			else if(r - b / 2 >= 2) System.out.println(b / 2 + 1);
		}
		else{
			if(r % 2 == 0) System.out.println(Math.min(r / 2, b));
			else if(b <= r / 2) System.out.println(b);
			else if(b - r / 2 >= 2) System.out.println(r / 2 + 1);
		}
	}
	else if (r == 0 && b == 0 && g != 0) System.out.println(0);
	else if (r == 0 && b != 0 && g == 0) System.out.println(0);
	else if (r != 0 && b == 0 && g == 0) System.out.println(0);
	else if(r != 0 && b != 0 && g != 0){
		if(r / table >= 2){
			if(g >= table) System.out.println(table);
			else if(b >= table - g) System.out.println(table);
			else System.out.println(g + b);
		}
		else if ( r / table == 1){
			if(g / 2 >= table) System.out.println(table);
			else if (b / 2 >= table - g / 2) System.out.println(table);
//			else if (g % 2 != 0 && b % 2 != 0){
//				if(b / 2 + g / 2 + 1 == table) System.out.println(table);
//				else if (r - table >= 2) System.out.println(table);
//			}
//			else if ((g % 2 != 0 && b % 2 == 0) || (g % 2 == 0 && b % 2 != 0)){
//				if(r - table >= 1) System.out.println(table);
//			}
			else{
				if(g + b >= table){
					long bLeft = b - (table - g);
					long rLeft = r - table;
					if(rLeft + bLeft >= table){
						System.out.println(table);
					}
					else{
						System.out.println(rLeft + bLeft);
					}
				}
			}
		}
		else{
			if(g / table >= 2){
				if(b >= table) System.out.println(table);
				else if(r >= table - b) System.out.println(table);
				else System.out.println(b + r);
			}
			else if ( g / table == 1){
				if(b / 2 >= table) System.out.println(table);
				else if (r / 2 >= table - b / 2) System.out.println(table);
//				else if (b % 2 != 0 && r % 2 != 0){
//					if(r / 2 + b / 2 + 1 == table) System.out.println(table);
//					else if (g - table >= 2) System.out.println(table);
//				}
//				else if ((b % 2 != 0 && r % 2 == 0) || (b % 2 == 0 && r % 2 != 0)){
//					if(g - table >= 1) System.out.println(table);
//					else
//				}
				else {
					if(r + b >= table){
						long bLeft = b - (table - r);
						long gLeft = g - table;
						if(gLeft + bLeft >= table){
							System.out.println(table);
						}
						else{
							System.out.println(gLeft + bLeft);
						}
					}
				}
			}
			else{
				if(b / table >= 2){
					if(r >= table) System.out.println(table);
					else if(g >= table - r) System.out.println(table);
					else System.out.println(r + g);
				}
				else if ( b / table == 1){
					if(r / 2 >= table) System.out.println(table);
					else if (g / 2 >= table - r / 2) System.out.println(table);
//					else if (r % 2 != 0 && g % 2 != 0){
//						if(g / 2 + r / 2 + 1 == table) System.out.println(table);
//						else if (b - table >= 2) System.out.println(table);
//					}
//					else if ((r % 2 != 0 && g % 2 == 0) || (r % 2 == 0 && g % 2 != 0)){
//						if(b - table >= 1) System.out.println(table);
//					}
					else{
						if(r + g >= table){
							long rLeft = r - (table - g);
							long bLeft = b - table;
							if(bLeft + rLeft >= table){
								System.out.println(table);
							}
							else{
								System.out.println(bLeft + rLeft);
							}
						}
					}
				}
			}
		}
	}
}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int ntc = 1;
//        ntc = in.nextInt();
            while ((ntc--) > 0) {
                long a = in.nextLong();
                long b = in.nextLong();
                long c = in.nextLong();
                out.println(_F.min((a + b + c) / 3, a + b + c - _F.max(a, b, c)));
            }
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

    }

    static class _F {
        public static <T extends Comparable<T>> T max(T... list) {
            T candidate = list[0];
            for (T i : list) {
                if (candidate.compareTo(i) < 0) {
                    candidate = i;
                }
            }
            return candidate;
        }

        public static <T extends Comparable<T>> T min(T... list) {
            T candidate = list[0];
            for (T i : list) {
                if (candidate.compareTo(i) > 0) {
                    candidate = i;
                }
            }
            return candidate;
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(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++];
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

import java.util.Arrays;
import java.util.Scanner;
/**
 * Created by yakoub on 03/04/15.
 */
public class TableDecorations {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        long[] arr = new long[3];
        for (int i = 0; i < 3; i++)
            arr[i] = scanner.nextInt();
        Arrays.sort(arr);
        if (arr[0] + arr[1] <= arr[2] / 2)
            System.out.println(arr[0]+arr[1]);
        else
            System.out.println((arr[0]+arr[1]+arr[2])/3);
    }
}

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

/**
 *
 * @author Saju
 *
 */

public class Main {

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

    private static final long INF = Long.MAX_VALUE;
    private static final int INT_INF = Integer.MAX_VALUE;
    private static final long NEG_INF = Long.MIN_VALUE;
    private static final int NEG_INT_INF = Integer.MIN_VALUE;
    private static final double EPSILON = 1e-10;

    private static final int MAX = 1000000007;

    private static final long MOD = 1000000007;

    private static final int MAXN = 10000000;
    private static final int MAXA = 100007;
    private static final int MAXLOG = 22;

	public static void main(String[] args) throws IOException {

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

//         InputReader in = new InputReader(new FileInputStream("src/test.in"));
//         PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("src/test.out")));

/*

*/

		long arr[] = new long[3];
		arr[0] = in.nextLong();
		arr[1] = in.nextLong();
		arr[2] = in.nextLong();

		Arrays.sort(arr);
		if(arr[0] + arr[1] <= arr[2] / 2) {
			out.println(arr[0] + arr[1]);
		}
		else {
			out.println((arr[0] + arr[1] + arr[2]) / 3L);
		}

		in.close();
		out.flush();
		out.close();
		System.exit(0);
	}

	private static boolean isPalindrome(String str) {
		StringBuilder sb = new StringBuilder();
		sb.append(str);
		String str1 = sb.reverse().toString();
		return str.equals(str1);
	}

	private static String getBinaryStr(int n, int len) {
		String str = Integer.toBinaryString(n);
		int k = str.length();
		for (int i = 1; i <= len - k; i++) {
			str = "0" + str;
		}

		return str;
	}

	private static String getBinaryStr(long n, int j) {
		String str = Long.toBinaryString(n);
		int k = str.length();
		for (int i = 1; i <= j - k; i++) {
			str = "0" + str;
		}

		return str;
	}

	private static long modInverse(long r) {
		return bigMod(r, MOD - 2, MOD);
	}

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

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

	private static long ceil(long n, long x) {
		long div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
	}

    private static int ceil(int n, int x) {
        int div = n / x;
        if(div * x != n) {
            div++;
        }
        return div;
    }

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

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

    private static int lcm(int a, int b) {
        return (a * b) / gcd(a, b);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        public int[] nextIntArr(int n) {
        	int arr[] = new int[n];
    		for(int i = 0; i < n; i++) {
    			arr[i] = nextInt();
    		}
    		return arr;
        }

        public long[] nextLongArr(int n) {
        	long arr[] = new long[n];
    		for(int i = 0; i < n; i++) {
    			arr[i] = nextLong();
    		}
    		return arr;
        }

        public int[] nextIntArr1(int n) {
        	int arr[] = new int[n + 1];
    		for(int i = 1; i <= n; i++) {
    			arr[i] = nextInt();
    		}
    		return arr;
        }

        public long[] nextLongArr1(int n) {
        	long arr[] = new long[n + 1];
    		for(int i = 1; i <= n; i++) {
    			arr[i] = nextLong();
    		}
    		return arr;
        }

        public void close() {
        	try {
        		if(reader != null) {
        			reader.close();
        		}
        	}
        	catch(Exception e) {

        	}

        }
    }

}

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

public class TableDecorations {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long[] b  = {sc.nextLong(), sc.nextLong(), sc.nextLong()};
        Arrays.sort(b);
        System.out.println(Math.min(b[0] + b[1], (b[0] + b[1] + b[2])/3));
    }
}

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

public class CR273_table_decorations {

    public static void main(String... args) throws IOException {
        MyScanner sc = new MyScanner();
        long[] colours = new long[3];
        for (int i = 0; i < 3; i++) {
            colours[i] = sc.nextLong();
        }
        Arrays.sort(colours);

        long triples = colours[0];
        colours[1] -= triples;
        colours[2] -= triples;

        long twos = colours[1] / 2;
        colours[1] = colours[1] % 2;
        colours[2] -= twos;

        long pairsToBroke = Math.min(colours[2] / 3, triples + twos);
        long twos2 = pairsToBroke * 2;

        colours[2] -= pairsToBroke * 3;
        twos2 += (colours[2] >= 2 && colours[1] == 1) ? 1 : 0;

        long tables = triples + twos - pairsToBroke + twos2;
        System.out.println(tables);
    }

    static class MyScanner {

        BufferedReader br;
        StringTokenizer st;

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

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

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

        private long nextLong() throws IOException {
            String next = next();
            return Long.parseLong(next);
        }
    }
}

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

public class ladder {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		long[] colors = { in.nextLong(), in.nextLong(), in.nextLong() };
		Arrays.sort(colors);
		if(colors[2]>=2*(colors[0]+colors[1])){
			System.out.println(colors[0]+colors[1]);
		}else{
			System.out.println((colors[0]+colors[1]+colors[2])/3);
		}
	}

}

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

public class C {
    public static void main (String [] args) {
        Scanner sc = new Scanner(System.in);
        long [] a = new long[3];

         a[0] = sc.nextInt();
         a[1] = sc.nextInt();
         a[2] = sc.nextInt();

         Arrays.sort(a);
        System.out.println(Math.min((a[0]+a[1]+a[2]) / 3L, a[0]+a[1]));
    }
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.util.InputMismatchException;

/**
 * Ashesh Vidyut (Drift King) *
 */
public class C {
    public static void main(String[] args) {
        try {
            InputReader in = new InputReader(System.in);
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
            long r = in.readLong();
            long g = in.readLong();
            long b = in.readLong();
            long ans = Math.max(r, Math.max(b, g));
            long res = ans / 2;
            if(r + g + b - ans >= res)
                out.write(Long.toString((r + g + b) / 3));
            else
                out.write(Long.toString(r + b + g - ans));
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class InputReader {
    private boolean finished = false;

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public InputReader(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++];
    }

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

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int length = readInt();
        if (length < 0)
            return null;
        byte[] bytes = new byte[length];
        for (int i = 0; i < length; i++)
            bytes[i] = (byte) read();
        try {
            return new String(bytes, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            return new String(bytes);
        }
    }

    public static boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    private String readLine0() {
        StringBuffer buf = new StringBuffer();
        int c = read();
        while (c != '\n' && c != -1) {
            if (c != '\r')
                buf.appendCodePoint(c);
            c = read();
        }
        return buf.toString();
    }

    public String readLine() {
        String s = readLine0();
        while (s.trim().length() == 0)
            s = readLine0();
        return s;
    }

    public String readLine(boolean ignoreEmptyLines) {
        if (ignoreEmptyLines)
            return readLine();
        else
            return readLine0();
    }

    public BigInteger readBigInteger() {
        try {
            return new BigInteger(readString());
        } catch (NumberFormatException e) {
            throw new InputMismatchException();
        }
    }

    public char readCharacter() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        return (char) c;
    }

    public double readDouble() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        double res = 0;
        while (!isSpaceChar(c) && c != '.') {
            if (c == 'e' || c == 'E')
                return res * Math.pow(10, readInt());
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        }
        if (c == '.') {
            c = read();
            double m = 1;
            while (!isSpaceChar(c)) {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, readInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                m /= 10;
                res += (c - '0') * m;
                c = read();
            }
        }
        return res * sgn;
    }

    public boolean isExhausted() {
        int value;
        while (isSpaceChar(value = peek()) && value != -1)
            read();
        return value == -1;
    }

    public String next() {
        return readString();
    }

    public boolean readBoolean() {
        return readInt() == 1;
    }
}

/*

LANG: JAVA
TASK: combo
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;

public class combo
{
	public static void main(String[] args) throws Exception
	{
		BufferedReader bR = new BufferedReader(new InputStreamReader(System.in));
		long[] thing = readLong(bR);
		Arrays.sort(thing);
		long thingy = thing[0]+thing[1]+thing[2];
		thingy/=3;

		if(thing[0]+thing[1]<thingy)
		{
			thingy = thing[0]+thing[1];
		}
		System.out.println(thingy);
	}

	static long fibbonaci(int n)
	{
		if(n<2)
		{
			return 1;
		}
		return fibbonaci(n-1)+fibbonaci(n-2);
	}

	static int findMinDiff(int[] array)
	{
		int min = Integer.MAX_VALUE;
		for(int a = 0;a<array.length-1;a++)
		{
			min = Math.min(min,array[a+1]-array[a]);
		}
		return min;
	}

	static int numUppercase(String a)
	{
		int num = 0;
		char[] thing = a.toCharArray();
		for(char c: thing)
		{
			if(c>='A'&&c<='Z')
			{
				num++;
			}
		}
		return num;
	}

	static char whichChar(char[][] array, int startX,int endX, int startY, int endY)
	{
		char test = array[startY][startX];
		for(int x = startX;x<endX;x++)
		{
			for(int y = startY;y<endY;y++)
			{
				if(array[y][x]!=test)
				{
					return '-';
				}
			}
		}
		return test;
	}

	public static void shuffle(int[] array)
	{
		Random random = new Random();
		for (int i = array.length - 1; i > 0; i--)
		{
			int index = random.nextInt(i + 1);

			int temp = array[index];
			array[index] = array[i];
			array[i] = temp;
		}
	}

	public static int[] readInt(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		int[] readArr = new int[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Integer.parseInt(temp[a]);
		}
		return readArr;
	}

	public static double[] readDouble(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		double[] readArr = new double[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Double.parseDouble(temp[a]);
		}
		return readArr;
	}

	public static long[] readLong(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		long[] readArr = new long[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Long.parseLong(temp[a]);
		}
		return readArr;
	}
}

import java.util.*;
import java.io.*;
import java.math.*;
public class Main{
	static long mod = (long)1e9+7;
	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	public static void main(String sp[])throws IOException{
		Scanner sc = new Scanner(System.in);
		ArrayList<Long> al = new ArrayList<>();
		int zero = 0;
		for(int i=0;i<3;i++){
			al.add(sc.nextLong());
			if(al.get(i)==0)
				zero++;
		}

		Collections.sort(al);
		/*if(zero==2){
			System.out.println("0");
			return;
		}
		if(zero==1){
			if(al.get(2)>=al.get(1)*2){
				System.out.println(al.get(1));
				return;
			}
			System.out.println((al.get(1)+al.get(2))/3);
			return;
		}*/

		if(al.get(2)>=(al.get(0)+al.get(1))*2)
			System.out.println(al.get(0)+al.get(1));
		else {
			long sum = al.get(0)+al.get(1)+al.get(2);
			System.out.println(sum/3);

		}
	}

	public static ArrayList<Integer> primefactor(int n){
		int sqrt = (int)Math.sqrt(n);
		ArrayList<Integer> al = new ArrayList<>();
		while(n%2==0){
			al.add(2);
			n/=2;
		}
		for(int i=3;i<=sqrt;i+=2){
			while(n%i==0){
				al.add(i);
				n/=i;
			}
		}
		if(n>2)
			al.add(n);
		return al;
	}

	public static long sum(long val){
		long fg =0 ;
		while(val!=0){
			fg+=val%10;
			val/=10;
		}
		return fg;
	}

	public static ArrayList<Integer> factor(int n){
		int sqrt = (int)Math.sqrt(n);
		ArrayList<Integer> al = new ArrayList<>();
		for(int i=1;i<=sqrt;i++){
			if(n%i!=0)
				continue;
			int first = i;
			int second = n/i;
			al.add(i);
			if(first==second){
				continue;
			}
			al.add(n/i);
		}
		return al;
	}

	public static long power(long x, long y)
		{

		long temp;
		if( y == 0l)
			return 1l;
		temp = power(x, y/2);
		if (y%2 == 0)
			return (temp%mod*temp%mod)%mod;
		else
			return (((x%mod*temp%mod)%mod)*temp)%mod;
	}

	public static ArrayList<Integer> comp(){
		ArrayList<Integer> al = new ArrayList<>();
			int n = (int)2e5;
			boolean arr[] = new boolean[n+1];
			int sqrt = (int)Math.sqrt(n);
			for(int i=2;i<=sqrt;i++){
				if(arr[i]==false){
					for(int j=i*i;j<=n;j+=i){
						arr[j]=true;
					}
				}
			}
			for(int i=2;i<=n;i++){
				if(arr[i]==false)
					al.add(i);
			}

		return al;
	}

	public static class pair{
		int x;
		int y;
		pair(int x, int y){
			this.x=x;
			this.y=y;
		}
	}

	public static class comp implements Comparator<pair>{
		public int compare(pair o1, pair o2){
			if(o1.y==o2.y){
				return o2.x-o1.x;
			}
			return o2.y-o1.y;
		}
	}

	static class Node{
		int node;
		int d;
		ArrayList<Integer> al = new ArrayList<>();
	}

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

	static class FastReader
	{
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public FastReader()
		{
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public FastReader(String file_name) throws IOException
		{
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String readLine() throws IOException
		{
			byte[] buf = new byte[64]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1)
			{
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException
		{
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
			{
				ret = ret * 10 + c - '0';
			}  while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException
		{
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException
		{
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');

			if (c == '.')
			{
				while ((c = read()) >= '0' && c <= '9')
				{
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException
		{
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException
		{
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException
		{
			if (din == null)
				return;
			din.close();
		}
	}
}

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

public class C
{
	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            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;
        }
    }

	public static void main(String[] args)
	{
		FastReader file = new FastReader();
		PrintWriter out = new PrintWriter(System.out);

		int r = file.nextInt();
		int g = file.nextInt();
		int b = file.nextInt();

		long[] arr = {r, g, b};

		long maxAns = (arr[0] + arr[1] + arr[2]) / 3;

		int min = 0;
		for (int i = 0; i < 3; i++)
		{
			if (arr[i] < arr[min])
			{
				min = i;
			}
		}

		int mid = min != 0 ? 0 : 1;

		for (int i = 0; i < 3; i++)
		{
			if (i == min)
			{
				continue;
			}
			if (arr[i] < arr[mid])
			{
				mid = i;
			}
		}

		out.println(Math.min(maxAns, arr[min] + arr[mid]));

		out.close();
	}

}

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

public class Main {

    static BufferedReader in;
    static PrintWriter out;
    static StringTokenizer tok;

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

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

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

    static long nexLong() throws IOException{
        return Long.parseLong(next());
    }
    public static void main(String[] args) throws IOException {
        // TODO Auto-generated method stub
        try{
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter( new OutputStreamWriter(System.out));
        } catch( Throwable e){
            e.printStackTrace();
        }
        long a= nextInt(); long b= nextInt(); long c= nextInt();
        if (2*(a+b) <=c) {
            out.println(a+b);
        } else if (2*(a+c)<=b){
            out.println(a+c);
        } else if(2*(c+b)<=a){
            out.println(c+b);
        } else if ((a==0&&b==0) || (a==0&&c==0) || (b==0&&c==0)){
            out.println(0);
        } else {
            long d =(a+b+c)/3;
            out.println(d);
        }
        out.close();
    }

}

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Solution {

    int n;
    void solve(InputReader in, PrintWriter out) {

        long[] color = new long[3];
        for (int i = 0; i < 3; i++) {
            color[i] = in.nextInt();
        }
        Arrays.sort(color);

        long ans = color[0]+color[1]+color[2];
        if(color[2] >= 2*(color[1] + color[0])) {
            ans -= (color[2] - 2*(color[1] + color[0]));
        }
        out.print(ans/3);

    }

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        new Solution().solve(in, out);
        out.close();
    }
}

class InputReader{
    BufferedReader reader;
    StringTokenizer st;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), (1<<15));
        st = null;
    }
    String next() {
        while (st == null || !st.hasMoreTokens()) {
            try {
                st = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return st.nextToken();
    }

    int nextInt() {return  Integer.parseInt(next());}
    long nextLong() {return  Long.parseLong(next());}
    double nextDouble() {return  Double.parseDouble(next());}
}

import java.util.*;

import org.omg.CORBA.INTERNAL;

import java.awt.List;
import java.io.*;
import java.lang.*;
import java.lang.reflect.Array;

public class code3 {

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		// Code starts..

		long r = in.nextLong();
		long g = in.nextLong();
		long b = in.nextLong();

		long ans = Math.min((r + g + b) / 3, Math.min(r + g, Math.min(r + b, g + b)));
		pw.println(ans);

		// code ends...

		pw.flush();
		pw.close();
	}

	public static double pow(double x, int n)
	{

		double ans = 1;
		for(int i=0; i<n; i++)
			ans *= x;
		return ans;
	}

	public static boolean check(String s1, String s2){

		boolean status = true;

        if(s1.length() != s2.length())
        {
            status = false;
        }
        else {
            char[] s1Array = s1.toLowerCase().toCharArray();

            char[] s2Array = s2.toLowerCase().toCharArray();
            Arrays.sort(s1Array);
            Arrays.sort(s2Array);
            status = Arrays.equals(s1Array, s2Array);
        }
        if(status)
        	return true;

        	return false;
    }

	public static long[][] mul(long[][] a, long[][] b){

		int n = a.length;
		int m = b[0].length;
		long[][] c = new long[n][m];

		for(int i=0; i<n; i++)
			for(int j=0; j<m; j++)
			{
				long tmp = 0;
				for(int k=0; k<a[0].length; k++)
					tmp =( (tmp+mod)%mod+(a[i][k]*b[k][j]+mod)%mod)%mod;
				c[i][j] = (tmp+mod)%mod;
			}

		return c;
	}

	public static long[][] pow(long[][] a,int  n)
	{

		long[][] res = a;
		while(n>0)
		{
			if(n%2==1)
			{
				res = mul(a, res);
			}

			a = mul(a, a);

			n/=2;

		}

		return res;

	}

	public static boolean isSubSequence(char[] str2, String str1) {

		int j = 0;
		int m = str1.length();
		int n = str2.length;

		for (int i = 0; i < n && j < m; i++)

			if (str1.charAt(j) == str2[i])

				j++;

		return (j == m);
	}

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

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

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

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

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

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}

	public static long c = 0;

	public static long mod = (long)Math.pow(10, 6)+3;
	public static int d;
	public static int p;
	public static int q;
	public static boolean flag;
	//public static long INF = Long.MAX_VALUE;

	public static void factSieve(int[] fact, long n) {

		for (int i = 2; i <= n; i += 2)
			fact[i] = 2;

		for (int i = 3; i <= n; i += 2) {
			if (fact[i] == 0) {
				fact[i] = i;

				for (int j = i; (long) j * i <= n; j++) {
					fact[(int) ((long) i * j)] = i;
				}
			}
		}

		/*
		 * int k = 1000; while(k!=1) { System.out.print(a[k]+" "); k /= a[k];
		 *
		 * }
		 */
	}

	public static long floorsqrt(long n) {
		long ans = 0;
		long l = 0;
		long r = n;
		long mid = 0;
		while (l <= r) {
			mid = (l + r) / 2;
			if (mid * mid == n)
				return mid;

			if (mid * mid > n) {
				r = mid - 1;
			} else {
				ans = mid;
				l = mid + 1;
			}

		}

		return ans;
	}

	public static long fun(int[] a, int[] b, int m, int n) {
		long result = 0;
		for (int i = 0; i < m; i++)
			for (int j = 0; j < m; j++) {
				long[] fib = new long[Math.max(2, n + 2)];
				fib[1] = a[i];
				fib[2] = b[j];
				for (int k = 3; k <= n; k++)
					fib[k] = (fib[k - 1] % mod + fib[k - 2] % mod) % mod;
				result = (result % mod + fib[n] % mod) % mod;
			}

		return result;

	}

	/*
	 * public static double slope(pair p1, pair p2) { double m = INF; if((p1.x -
	 * p2.x)!=0) m = p1.y - p2.y/(p1.x - p2.x);
	 *
	 *
	 * return Math.abs(m);
	 *
	 * }
	 */

	public static int gcd(int p2, int p22) {
		if (p2 == 0)
			return (int) p22;
		return gcd(p22 % p2, p2);
	}

	public static int findGCD(int arr[], int n) {
		int result = arr[0];
		for (int i = 1; i < n; i++)
			result = gcd(arr[i], result);

		return result;
	}

	public static void nextGreater(long[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] < a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] >= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static void nextGreaterRev(long[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] < arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] >= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmallerRev(int[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] > arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] <= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmaller(int[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] > a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] <= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static long lcm(int[] numbers) {
		long lcm = 1;
		int divisor = 2;
		while (true) {
			int cnt = 0;
			boolean divisible = false;
			for (int i = 0; i < numbers.length; i++) {
				if (numbers[i] == 0) {
					return 0;
				} else if (numbers[i] < 0) {
					numbers[i] = numbers[i] * (-1);
				}
				if (numbers[i] == 1) {
					cnt++;
				}
				if (numbers[i] % divisor == 0) {
					divisible = true;
					numbers[i] = numbers[i] / divisor;
				}
			}
			if (divisible) {
				lcm = lcm * divisor;
			} else {
				divisor++;
			}
			if (cnt == numbers.length) {
				return lcm;
			}
		}
	}

	public static long fact(long n) {

		long factorial = 1;
		for (int i = 1; i <= n; i++) {
			factorial *= i;
		}
		return factorial;
	}

	public static int lowerLimit(int[] a, int n) {
		int ans = 0;

		int ll = 0;
		int rl = a.length - 1;
		// System.out.println(a[rl]+" "+n);
		if (a[0] > n)
			return 0;
		if (a[0] == n)
			return 1;
		else if (a[rl] <= n)
			return rl + 1;

		while (ll <= rl) {

			int mid = (ll + rl) / 2;
			if (a[mid] == n) {
				ans = mid + 1;
				break;
			}

			else if (a[mid] > n) {
				rl = mid - 1;

			} else {
				ans = mid + 1;
				ll = mid + 1;
			}
		}

		return ans;
	}

	public static long choose(long total, long choose) {
		if (total < choose)
			return 0;
		if (choose == 0 || choose == total)
			return 1;
		return (choose(total - 1, choose - 1) + choose(total - 1, choose)) % mod;
	}

	public static int[] suffle(int[] a, Random gen) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}
		return a;
	}

	public static int floorSearch(int arr[], int low, int high, int x) {
		if (low > high)
			return -1;

		if (x > arr[high])
			return high;
		int mid = (low + high) / 2;

		if (mid > 0 && arr[mid - 1] < x && x < arr[mid])
			return mid - 1;

		if (x < arr[mid])
			return floorSearch(arr, low, mid - 1, x);

		return floorSearch(arr, mid + 1, high, x);
	}

	public static void swap(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
	}

	public static ArrayList<Integer> primeFactorization(int n) {
		ArrayList<Integer> a = new ArrayList<Integer>();
		for (int i = 2; i * i <= n; i++) {
			while (n % i == 0) {
				a.add(i);
				n /= i;
			}
		}
		if (n != 1)
			a.add(n);
		return a;
	}

	public static void sieve(boolean[] isPrime, int n) {
		for (int i = 1; i < n; i++)
			isPrime[i] = true;

		isPrime[0] = false;
		isPrime[1] = false;

		for (int i = 2; i * i < n; i++) {
			if (isPrime[i] == true) {
				for (int j = (2 * i); j < n; j += i)
					isPrime[j] = false;
			}
		}
	}

	public static int lowerbound(ArrayList<Long> net, long c2) {
		int i = Collections.binarySearch(net, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int lowerboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int uperbound(ArrayList<Integer> list, int c2) {
		int i = Collections.binarySearch(list, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static int uperboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static long[] sort(long[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			long temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int[] sort(int[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int GCD(int a, int b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static void extendedEuclid(int A, int B) {
		if (B == 0) {
			d = A;
			p = 1;
			q = 0;
		} else {
			extendedEuclid(B, A % B);
			int temp = p;
			p = q;
			q = temp - (A / B) * q;
		}
	}

	public static long LCM(long a, long b) {
		return (a * b) / GCD(a, b);
	}

	public static int LCM(int a, int b) {
		return (a * b) / GCD(a, b);
	}

	public static int binaryExponentiation(int x, int n) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = x * x;
			n = n / 2;
		}
		return result;
	}

	public static int[] countDer(int n) {
		int der[] = new int[n + 1];

		der[0] = 1;
		der[1] = 0;
		der[2] = 1;

		for (int i = 3; i <= n; ++i)
			der[i] = (i - 1) * (der[i - 1] + der[i - 2]);

		// Return result for n
		return der;
	}

	static long binomialCoeff(int n, int k) {
		long C[][] = new long[n + 1][k + 1];
		int i, j;

		// Calculate value of Binomial Coefficient in bottom up manner
		for (i = 0; i <= n; i++) {
			for (j = 0; j <= Math.min(i, k); j++) {
				// Base Cases
				if (j == 0 || j == i)
					C[i][j] = 1;

				// Calculate value using previosly stored values
				else
					C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
			}
		}

		return C[n][k];
	}

	public static long binaryExponentiation(long x, long n) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = (x % mod * x % mod) % mod;
			n = n / 2;
		}
		return result;
	}

	public static int modularExponentiation(int x, int n, int M) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static long modularExponentiation(long x, long n, long M) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static int modInverse(int A, int M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static long sie(long A, long M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static boolean checkYear(int year) {
		if (year % 400 == 0)
			return true;

		if (year % 100 == 0)
			return false;

		if (year % 4 == 0)
			return true;
		return false;
	}

	public static boolean isPrime(int n) {

		if (n <= 1)
			return false;
		if (n <= 3)
			return true;

		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6) {
			if (n % i == 0 || n % (i + 2) == 0)
				return false;
		}

		return true;
	}

	static class pair implements Comparable<pair>

	{
		Long x, y;

		pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		public int compareTo(pair o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);

			return result;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Object o) {
			if (o instanceof pair) {
				pair p = (pair) o;
				if(p.x-x==0 && p.y-y==0)
					return true;
				else
				return false;
			}
			return false;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
		}

	}

	static class triplet implements Comparable<triplet> {
		Integer x, y, z;

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

		public int compareTo(triplet o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);
			if (result == 0)
				result = z.compareTo(o.z);

			return result;
		}

		public boolean equlas(Object o) {
			if (o instanceof triplet) {
				triplet p = (triplet) o;
				return x == p.x && y == p.y && z == p.z;
			}
			return false;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode() + new Long(z).hashCode();
		}
	}

	static class query implements Comparable<query> {
		Integer l,r, x, idx, tp;

		query(int l, int r, int x, int id, int tp)
		{
			this.l = l ;
			this.r = r;
			this.x = x;
			this.idx = id;
			this.tp = tp;
		}

		public int compareTo(query o) {
			int result = x.compareTo(o.x);

			return result;
		}

	}

	/*
	 * static class node implements Comparable<node>
	 *
	 * { Integer x, y, z; node(int x,int y, int z) { this.x=x; this.y=y; this.z=z; }
	 *
	 * public int compareTo(pair o) { int result = x.compareTo(o.x); if(result==0)
	 * result = y.compareTo(o.y); if(result==0) result = z.compareTo(z); return
	 * result; }
	 *
	 * @Override public int compareTo(node o) { // TODO Auto-generated method stub
	 * return 0; } }
	 */
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C478
{

	public static int mod = 1000000007;
	static FasterScanner in = new FasterScanner();
	static PrintWriter out = new PrintWriter(System.out);

	public static void main(String[] args)
	{

		long[] arr=new long[3];
		for(int i=0;i<3;i++)
		{
			arr[i]=in.nextInt();
		}
		Arrays.sort(arr);
		if(arr[2]>=2*(arr[0]+arr[1]))
		{
			System.out.println((arr[0]+arr[1]));
			return;
		}
		long ans=(arr[0]+arr[1]+arr[2])/3;
		out.println(ans);
		out.close();

	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FasterScanner
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

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

		public String nextLine()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do
			{
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			long res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			int res = 0;
			do
			{
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			while (!isSpaceChar(c));
			return res * sgn;
		}

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

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

		private boolean isSpaceChar(int c)
		{
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c)
		{
			return c == '\n' || c == '\r' || c == -1;
		}
	}

}

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class Main {

    static void solve() {
        Scanner scan = new Scanner(System.in);
        long r = scan.nextLong();
        long g = scan.nextLong();
        long b = scan.nextLong();

        long[] arr = new long[]{r, g, b};
        Arrays.sort(arr);

        long res = 0;

        if(arr[2]>=2*(arr[0]+arr[1])) {
            res = arr[0]+arr[1];
        } else{
            res = (arr[0]+arr[1]+arr[2])/3;
        }

        System.out.println(res);
    }

    public static void main(String[] args) {
        solve();
        //        Main m = new Main();
        //        Scanner scan = new Scanner(System.in);

        //        long n = scan.nextLong();
        //        long r = scan.nextLong();
        //        List<Long> list = new ArrayList<>();
        ////        int[] arr = new int[n];
        //        for (long i=0;i<n;i++){
        //            list.add(scan.nextLong());
        //        }
//            System.out.println(ch);
        //        solve(n, arr);
        //        scan.close();
    }

    static int[] countSort() {
        int[] input = new int[]{1, 4, 1, 2, 7, 5, 2};
        int[] output = new int[input.length];
        int[] count = new int[8];

        for (int i = 0; i < input.length; i++) {
            count[input[i]]++;
        }

        //forgot to sum those values, iterate over count
        int sum = 0;
        for (int i = 0; i < count.length; i++) {
            sum += count[i];
            count[i] = sum;
        }

        for (int i = 0; i < input.length; i++) {
            int pos = count[input[i]];
            output[pos - 1] = input[i];
            count[input[i]]--;
        }
        return output;
    }

    static class LRUCache {
        Map<Integer, Node> map;
        Node front;
        Node tail;
        int capacity;

        public LRUCache(int capacity) {
            map = new HashMap<>(capacity);
            this.capacity = capacity;
        }

        public int get(int key) {
            if (!map.containsKey(key)) {
                return -1;
            }
            Node node = map.get(key);
            if (node == front) {
                return front.data;
            }
            if (node == tail) {
                tail = node.prev;
            }
            front.prev = node;
            node.prev.next = node.next;
            if (node.next != null) {
                node.next.prev = node.prev;
            }
            node.next = front;
            node.prev = null;
            front = node;

            return front.data;
        }

        public void put(int key, int value) {
            Node node = new Node(key, value);
            ;
            if (front == null) {
                front = node;
                tail = node;
                map.put(key, node);
                return;
            }
            if (map.containsKey(key)) {
                node = map.get(key);
                node.data = value;
                if (node == front) {
                    map.put(key, node);
                    return;
                }
                if (node == tail) {
                    tail = node.prev;
                }
                front.prev = node;
                node.prev.next = node.next;
                if (node.next != null) {
                    node.next.prev = node.prev;
                }
                node.next = front;
                node.prev = null;
                front = node;
                map.put(key, node);
            } else if (map.size() < capacity) {
                front.prev = node;
                node.next = front;
                node.prev = null;
                front = node;
                map.put(key, node);

            } else {
                //remove a tail, insert to front
                map.remove(tail.key);
                if (tail.prev != null) {
                    tail.prev.next = null;
                }
                tail = tail.prev;

                front.prev = node;
                node.next = front;
                node.prev = null;
                front = node;
                map.put(key, node);
            }
        }
    }

    static class Node {
        int key;
        int data;
        Node next;
        Node prev;

        Node(int key, int data) {
            this.key = key;
            this.data = data;
        }
    }

    static class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }

    static class Trie {
        void add(String word) {

        }

        boolean search(String w) {
            return false;
        }
    }

    static class Node1 {
        public int val;
        public List<Node1> children;

        public Node1() {
        }

        public Node1(int _val, List<Node1> _children) {
            val = _val;
            children = _children;
        }
    }

    ;

    static class TrieNode {

    }

    static class KvNode implements Comparable<KvNode> {
        String key;
        int freq;

        public KvNode(String key, int freq) {
            this.key = key;
            this.freq = freq;
        }

        @Override
        public int compareTo(KvNode o) {
            if (this.key.equals(o.key)) {
                return 0;
            }
            return Integer.compare(o.freq, this.freq);
        }
    }

    static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

}

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

public class Main {
	MyScanner sc = new MyScanner();
	Scanner sc2 = new Scanner(System.in);
	long start = System.currentTimeMillis();
	long fin = System.currentTimeMillis();
	final int MOD = 1000000007;
	int[] dx = { 1, 0, 0, -1 };
	int[] dy = { 0, 1, -1, 0 };

	void run() {
		long[] c = sc.nextLongArray(3);
		Arrays.sort(c);
		long sum = c[0] + c[1] + c[2];
		if(c[0] + c[1] >= c[2]  / 2) {
			System.out.println(sum / 3);
		} else {
			System.out.println(c[0] + c[1]);
		}
	}

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

	void debug(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	void debug2(long[][] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}

	boolean inner(int h, int w, int limH, int limW) {
		return 0 <= h && h < limH && 0 <= w && w < limW;
	}

	void swap(char[] x, int a, int b) {
		char tmp = x[a];
		x[a] = x[b];
		x[b] = tmp;
	}

	// find minimum i (k <= a[i])
	int lower_bound(int a[], int k) {
		int l = -1;
		int r = a.length;
		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (k <= a[mid])
				r = mid;
			else
				l = mid;
		}
		// r = l + 1
		return r;
	}

	// find minimum i (k < a[i])
	int upper_bound(int a[], int k) {
		int l = -1;
		int r = a.length;
		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (k < a[mid])
				r = mid;
			else
				l = mid;
		}
		// r = l + 1
		return r;
	}

	int gcd(int a, int b) {
		return a % b == 0 ? b : gcd(b, a % b);
	}

	int lcm(int a, int b) {
		return a * b / gcd(a, b);
	}

	boolean palindrome(String s) {
		for (int i = 0; i < s.length() / 2; i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				return false;
			}
		}
		return true;
	}

	class MyScanner {
		int nextInt() {
			try {
				int c = System.in.read();
				while (c != '-' && (c < '0' || '9' < c))
					c = System.in.read();
				if (c == '-')
					return -nextInt();
				int res = 0;
				do {
					res *= 10;
					res += c - '0';
					c = System.in.read();
				} while ('0' <= c && c <= '9');
				return res;
			} catch (Exception e) {
				return -1;
			}
		}

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

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

		String next() {
			try {
				StringBuilder res = new StringBuilder("");
				int c = System.in.read();
				while (Character.isWhitespace(c))
					c = System.in.read();
				do {
					res.append((char) c);
				} while (!Character.isWhitespace(c = System.in.read()));
				return res.toString();
			} catch (Exception e) {
				return null;
			}
		}

		int[] nextIntArray(int n) {
			int[] in = new int[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextInt();
			}
			return in;
		}

		int[][] nextInt2dArray(int n, int m) {
			int[][] in = new int[n][m];
			for (int i = 0; i < n; i++) {
				in[i] = nextIntArray(m);
			}
			return in;
		}

		double[] nextDoubleArray(int n) {
			double[] in = new double[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextDouble();
			}
			return in;
		}

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

		char[][] nextCharField(int n, int m) {
			char[][] in = new char[n][m];
			for (int i = 0; i < n; i++) {
				String s = sc.next();
				for (int j = 0; j < m; j++) {
					in[i][j] = s.charAt(j);
				}
			}
			return in;
		}
	}
}

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

public class C478 {

	public static void main(String[] args) throws NumberFormatException, IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] a = br.readLine().split(" ");
		long[] arr = new long[3];
		arr[0] = Integer.parseInt(a[0]);
		arr[1] = Integer.parseInt(a[1]);
		arr[2] = Integer.parseInt(a[2]);
		Arrays.sort(arr);
		long ans = 0;
		if(2*arr[0] + 2*arr[1] <= arr[2])
			ans = arr[0] + arr[1];
		else ans = (arr[0] + arr[1] + arr[2])/3;
		System.out.println(ans);
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            long arr[] = new long[3];
            arr[0] = in.scanInt();
            arr[1] = in.scanInt();
            arr[2] = in.scanInt();
            Arrays.sort(arr);
            long ans = arr[0] + arr[1];
            if (ans * 2 >= arr[2]) {
                out.println((ans + arr[2]) / 3);
            } else {
                out.println(ans);
            }
        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}

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

public class C {
	FastScanner in = new FastScanner(System.in);
	PrintWriter out = new PrintWriter(System.out);

	public void run() {
		long[] nums = in.nextLongArray(3);

		Arrays.sort(nums);

		long res = 0;

		if ((nums[0] + nums[1]) * 2 < nums[2]) res += (nums[0] + nums[1]);
		else res += (nums[0] + nums[1] + nums[2]) / 3;

		System.out.println(res);

		out.close();
	}

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

	public void mapDebug(int[][] a) {
		System.out.println("--------map display---------");

		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[i].length; j++) {
				System.out.printf("%3d ", a[i][j]);
			}
			System.out.println();
		}

		System.out.println("----------------------------");
		System.out.println();
	}

	public void debug(Object... obj) {
		System.out.println(Arrays.deepToString(obj));
	}

	class FastScanner {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastScanner(InputStream stream) {
			this.stream = stream;
			//stream = new FileInputStream(new File("dec.in"));

		}

		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++];
		}

		boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		boolean isEndline(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

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

		int[] nextIntArray(int n) {
			int[] array = new int[n];
			for (int i = 0; i < n; i++)
				array[i] = nextInt();

			return array;
		}

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

		long[] nextLongArray(int n) {
			long[] array = new long[n];
			for (int i = 0; i < n; i++)
				array[i] = nextLong();

			return array;
		}

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

		double[] nextDoubleArray(int n) {
			double[] array = new double[n];
			for (int i = 0; i < n; i++)
				array[i] = nextDouble();

			return array;
		}

		String next() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		String[] nextStringArray(int n) {
			String[] array = new String[n];
			for (int i = 0; i < n; i++)
				array[i] = next();

			return array;
		}

		String nextLine() {
			int c = read();
			while (isEndline(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}
	}
}

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

public class Program {

    private static PrintWriter out;

    private static <T> void mprintln(T ... ar){
        for(T i: ar) out.print(i + " ");
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException{

        // Input from file
        // File inputFile = new File("JavaFile.txt");
        // File outputFile = new File("JavaOutputFile.txt");
        // FileReader fileReader = new FileReader(inputFile);
        // Here it ends

        MyScanner sc = new MyScanner();
        // MyScanner sc = new MyScanner(fileReader);

        out = new PrintWriter(new BufferedOutputStream(System.out)); // Output to console
        // out = new PrintWriter(new PrintStream(outputFile)); // Output to file

        getAns(sc);

        out.close();
    }

    private static void getAns(MyScanner sc){
        long[] ar = sc.nlArr0(3);
        Arrays.sort(ar);

        long ans = (ar[2] - ar[1]) / 2;
        ans = Math.min(ar[0], ans);
        ar[0] -= ans;
        ar[2] -= 2 * ans;

        ar[1] -= ar[0];
        ar[2] -= ar[0];
        ans += ar[0];
        ar[0] = 0;

        if(ar[1] + ar[2] < 3){
            out.println(ans);
            return;
        }

//        out.println(Arrays.toString(ar));

        long diff = ar[2] - ar[1];
        diff = Math.min(ar[1], diff);
        ans += diff;
        ar[1] -= diff;
        ar[2] -= 2 * diff;

        ans += ar[1] / 3 * 2;
        ar[1] %= 3;

        if(ar[1] == 2) ++ans;

        out.println(ans);

    }

    static class MyScanner{
        BufferedReader br;
	StringTokenizer st;

	MyScanner(FileReader fileReader){
            br = new BufferedReader(fileReader);
	}

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

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

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

	char nc(){
            return nn().charAt(0);
	}

	int ni(){
            return Integer.parseInt(nn());
	}

	long nl(){
            return Long.parseLong(nn());
	}

	double nd(){
            return Double.parseDouble(nn());
	}

	int[] niArr0(int n){
            int[] ar = new int[n];
            for(int i = 0; i < n; i++) ar[i] = ni();
            return ar;
	}

        int[] niArr1(int n){
            int[] ar = new int[n + 1];
            for(int i = 1; i <= n; i++) ar[i] = ni();
            return ar;
	}

        long[] nlArr0(int n){
            long[] ar = new long[n];
            for(int i = 0; i < n; i++) ar[i] = nl();
            return ar;
        }

        long[] nlArr1(int n){
            long[] ar = new long[n + 1];
            for(int i = 1; i <= n; i++) ar[i] = nl();
            return ar;
        }
    }
}

import java.util.*;
import java.io.*;
public class Prac {
	static Map<Integer, Integer>[] gr;
	static int[] par;
	static boolean[] in;
	static long[] dis;

	public static void main(String[] args){
		FastReader sc=new FastReader();
		PrintStream ps=System.out;

		int r=sc.nextInt(), g=sc.nextInt(), b=sc.nextInt();
		int[] ar=new int[]{r, g, b};
		Arrays.sort(ar);

		int ans=Math.min(ar[1]-ar[0],(ar[2]-ar[1])/2);
		ar[1]-=ans;
		ar[2]-=2*ans;

		int d=Math.min(ar[0], (ar[2]-ar[1])/3);
		ans+=2*d;
		ar[0]-=d;ar[1]-=d;ar[2]-=4*d;

		d=ar[0]-ar[0]%2;
		ans+=d;
		ar[0]-=d;ar[1]-=d;ar[2]-=d;

		if(ar[0]==1){
			if(ar[2]>1){
				ar[0]--;ar[2]-=2;
			}else{
				ar[0]--;ar[1]--;ar[2]--;
			}
			ans++;
		}

		Arrays.sort(ar);
		int x=ar[1], y=ar[2];
		d=Math.min(y-x, Math.min(x, y/2));
		ans+=d;
		x-=d;
		y-=2*d;

		if(x!=0) ans+=(x+y)/3;
		ps.println(ans);

	}

	public static void dfs(int v, int m, long dist, long min) {
		in[v]=true;

		if(v!=m && dist<min) {
			Set<Map.Entry<Integer, Integer>> set=gr[v].entrySet();

			for(Map.Entry<Integer, Integer> e: set){
				int nv=e.getKey(), w=e.getValue();
				if(!in[nv]){
					dfs(nv, m, dist+w, min);
					min=Math.min(min-w-dist, dis[nv])+w+dist;
					if(dis[v]-w>dis[nv]){
						par[nv]=v;
						dis[v]=dis[nv]+w;
					}
				}
			}
		}
		in[v]=false;
	}
}

class FastReader  {
    BufferedReader br;
    StringTokenizer st;

    public FastReader()
    {
        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;
    }
}

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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long[] ar = new long[]{in.nextLong(), in.nextLong(), in.nextLong()};
            Arrays.sort(ar);
            long ans = ar[0];
            long k3 = ar[0];
            if (k3 > 0) for (int i = 0; i < ar.length; i++) ar[i] -= k3;
            if (ar[2] >= 2 * ar[1]) {
                ans += ar[1];
                ar[2] -= 2 * ar[1];
                ar[1] = 0;
            } else {
                long diff = ar[2] - ar[1];
                ar[2] -= 2 * diff;
                ar[1] -= diff;
                ans += diff;

                long tt = ar[1] / 3;
                ans += 2 * tt;
                ar[2] -= tt * 3;
                ar[1] -= tt * 3;
                if (ar[1] == 2) {
                    ans++;
                    ar[1] = 1;
                    ar[2] -= 2;
                }

//            if (ar[1] == 1) {
//                if (ar[2] >= 2) {
//                    ans++;
//                    ar[2] -= 2;
//                    ar[1] = 0;
//                }
//            } else if (ar[1] == 2) {
//                if (ar[2] >= 4) {
//                    ans += 2;
//                    ar[1] = 0;
//                    ar[2] -= 4;
//                } else {
//                    ans++;
//                    ar[1] = 1;
//                    ar[2] -= 2;
//                }
//            }
            }

            Arrays.sort(ar);
            long ttt = Math.min(k3, ar[2] / 3);
            ans += ttt;

            out.println(ans);
        }

    }

    static class InputReader {
        StringTokenizer st;
        BufferedReader br;

        public InputReader(InputStream is) {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            this.br = br;
        }

        public String next() {
            if (st == null || !st.hasMoreTokens()) {
                String nextLine = null;
                try {
                    nextLine = br.readLine();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                if (nextLine == null)
                    return null;
                st = new StringTokenizer(nextLine);
            }
            return st.nextToken();
        }

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

    }
}

import java.util.Scanner;
public class TSasd {

	public static void main(String[] args) {

		long r, b, g,x,temp;
		Scanner input=new Scanner(System.in);
		r=input.nextLong();
		b=input.nextLong();
		g=input.nextLong();

		if(r<b){
			temp=r;
			r=b;
			b=temp;
		}
		else if (r<g){
			temp=r;
			r=g;
			g=temp;
		}
		else{
			r=r;
			b=b;
			g=g;
		}

		x=saveMeAgain(r,b,g);
		System.out.print(x);

	}

	public static long saveMe(long a,long d,long c){
		long y;
		if(a>=2*(c+d)){
			y=(c+d);
		}
		else{
			y=(a+c+d)/3;
		}
		return y;
	}
	public static long saveMeAgain(long d,long e,long f){
		long y;
		if((d==0 || e==0 || f==0) && (d+f==0 || d+e==0 || e+f==0)){
			y=0;
		}
		else if((d*e*f==0) && (d+f==1 || f+e==1 || d+e==1)){
			y=1;
		}
		else if((d==0 || e==0 || f==0) && (d*f>0 || f*e>0 || d*e>0)){

			y=saveMe(d,e,f);
		}

		else{
			y=saveMe(d,e,f);
		}

		return y;
	}

}

import java.util.Arrays;
import java.util.Scanner;
/**
 * Created by yakoub on 03/04/15.
 */
public class TableDecorations {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        long[] arr = new long[3];
        for (int i = 0; i < 3; i++)
            arr[i] = scanner.nextInt();
        Arrays.sort(arr);
        if (arr[0] + arr[1] <= arr[2] / 2)
            System.out.println(arr[0]+arr[1]);
        else
            System.out.println((arr[0]+arr[1]+arr[2])/3);
    }
}

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

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

	void solve()
	{
		long a[] = na(3);
		Arrays.sort(a);

		if((2*(a[0]+a[1]))<=a[2]) out.println(a[0]+a[1]);
		else out.println((a[0]+a[1]+a[2])/3);
	}

	void run() throws Exception
	{
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

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

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private long[] na(int n)
	{
		long[] a = new long[n];
		for(int i = 0;i < n;i++)a[i] = nl();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.TreeMap;

public class D {
	public static long[] dp;
	public static TreeMap<Integer, Integer> map;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		InputReader s = new InputReader(System.in);
		PrintWriter p = new PrintWriter(System.out);
		long[] arr = new long[3];
		arr[0] = s.nextLong();
		arr[1] = s.nextLong();
		arr[2] = s.nextLong();
		int ans = 0;
		Arrays.sort(arr);
		long diff = arr[2] - arr[1];
		if (arr[1] - diff >= arr[0]) { // b=c
			ans += diff;
			arr[1] -= diff;
			arr[2] -= 2 * diff;
			diff = arr[1] - arr[0];
			ans += 2 * ((diff) / 3);
			arr[1] -= (3 * (diff / 3));
			arr[2] -= (3 * (diff / 3));
			ans += arr[0];
			arr[1] -= arr[0];
			arr[2] -= arr[0];
			long b = arr[1];
			long c = arr[2];
			if (arr[1] >= 1 && arr[2] >= 2) {
				ans++;
			}
			System.out.println(ans);
			return;
		} else { // a=b
			diff = arr[1] - arr[0];
			ans += diff;
			arr[1] -= diff;
			arr[2] -= 2 * diff;
			if (arr[2] >= 4 * arr[0]) {
				ans += 2 * arr[0];
				arr[1] -= arr[0];
				arr[2] -= 4 * arr[0];
				if (arr[2] >= 2 && arr[1] == 1)
					ans++;
				System.out.println(ans);
				return;
			} else {
				long a = arr[0];
				long b = arr[1];
				long c = arr[2];
				ans += 2 * ((c - a) / 3);
				a -= (c - a) / 3;
				b -= (c - a) / 3;
				c -= ((c - a) / 3) * 4;
				ans += a;
				b -= a;
				c -= a;
				if (b >= 1 && c >= 2)
					ans++;
				System.out.println(ans);
			}
		}
		p.flush();
		p.close();
	}

	public static long getmax(int i) {
		if (i > map.lastKey()) {
			return 0;
		}
		if (!map.containsKey(i)) {
			long ans = getmax(i + 1);
			dp[i] = ans;
			return ans;
		}
		long ans1 = i * map.get(i) + getmax(i + 2);
		long ans2 = getmax(i + 1);
		long ans = Math.max(ans1, ans2);
		dp[i] = ans;
		return ans;
	}

	static class pair implements Comparable<pair> {
		Long x, y;

		pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		public int compareTo(pair o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);

			return result;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Object o) {
			if (o instanceof pair) {
				pair p = (pair) o;
				return p.x - x == 0 && p.y - y == 0;
			}
			return false;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
		}
	}

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

	public static ArrayList<Long> Divisors(long n) {
		ArrayList<Long> div = new ArrayList<>();

		for (long i = 1; i <= Math.sqrt(n); i++) {
			if (n % i == 0) {
				div.add(i);
				if (n / i != i)
					div.add(n / i);
			}
		}
		return div;
	}

	public static int BinarySearch(long[] a, long k) {
		int n = a.length;
		int i = 0, j = n - 1;
		int mid = 0;

		if (k < a[0])
			return 0;
		else if (k >= a[n - 1])
			return n;
		else {
			while (j - i > 1) {
				mid = (i + j) / 2;

				if (k >= a[mid])
					i = mid;
				else
					j = mid;
			}
		}

		return i + 1;
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static long LCM(long a, long b) {
		return (a * b) / GCD(a, b);
	}

//	static class pair implements Comparable<pair> {
//		Integer x, y;
//
//		pair(int x, int y) {
//			this.x = x;
//			this.y = y;
//		}
//
//		public int compareTo(pair o) {
//			int result = x.compareTo(o.x);
//			if (result == 0)
//				result = y.compareTo(o.y);
//
//			return result;
//		}
//
//		public String toString() {
//			return x + " " + y;
//		}
//
//		public boolean equals(Object o) {
//			if (o instanceof pair) {
//				pair p = (pair) o;
//				return p.x - x == 0 && p.y - y == 0;
//			}
//			return false;
//		}
//
//		public int hashCode() {
//			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
//		}
//	}

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

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

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

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

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

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}

	static class CodeX {
		public static void sort(long arr[]) {
			merge_sort(arr, 0, arr.length - 1);
		}

		private static void merge_sort(long A[], long start, long end) {
			if (start < end) {
				long mid = (start + end) / 2;
				merge_sort(A, start, mid);
				merge_sort(A, mid + 1, end);
				merge(A, start, mid, end);
			}

		}

		private static void merge(long A[], long start, long mid, long end) {
			long p = start, q = mid + 1;
			long Arr[] = new long[(int) (end - start + 1)];
			long k = 0;

			for (int i = (int) start; i <= end; i++) {
				if (p > mid)
					Arr[(int) k++] = A[(int) q++];

				else if (q > end)
					Arr[(int) k++] = A[(int) p++];

				else if (A[(int) p] < A[(int) q])
					Arr[(int) k++] = A[(int) p++];

				else
					Arr[(int) k++] = A[(int) q++];
			}
			for (int i = 0; i < k; i++) {
				A[(int) start++] = Arr[i];
			}

		}

	}

}

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

public class C {

	static class Scanner{
		BufferedReader br=null;
		StringTokenizer tk=null;
		public Scanner(){
			br=new BufferedReader(new InputStreamReader(System.in));
		}
		public String next() throws IOException{
			while(tk==null || !tk.hasMoreTokens())
				tk=new StringTokenizer(br.readLine());
			return tk.nextToken();
		}
		public int nextInt() throws NumberFormatException, IOException{
			return Integer.valueOf(next());
		}
		public long nextLong() throws NumberFormatException, IOException{
			return Long.valueOf(next());
		}
		public double nextDouble() throws NumberFormatException, IOException{
			return Double.valueOf(next());
		}
	}

	public static void main(String args[]) throws NumberFormatException, IOException{
		Scanner sc = new Scanner();
		long[] a = new long[3];
		for(int i = 0; i < 3; i++)
			a[i] = sc.nextLong();
		Arrays.sort(a);
		if( 2*a[0] + 2*a[1] <= a[2])
			System.out.println(a[0] + a[1]);
		else
			System.out.println((a[0] + a[1] + a[2])/3);
	}

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Round_273_Div_2C {

	private static BufferedReader in;
	private static StringTokenizer st;
	private static PrintWriter out;

	public static void main(String[] args) throws Exception {
		standart();
//		file("defense");
		long a[] = new long [3];
		for (int i = 0; i < 3; i++) {
			a[i] = nextInt();
		}
		Arrays.sort(a);
		if(2 * (a[0] + a[1]) <= a[2]){
			a[2] = 2 * (a[0] + a[1]);
		}
		System.out.println((a[0]+a[1]+a[2])/3);
		out.close();
	}

	private static double nextDouble() throws Exception {
		return Double.parseDouble(next());
	}

	private static long nextLong() throws Exception {
		return Long.parseLong(next());
	}

	private static int nextInt() throws Exception {
		return Integer.parseInt(next());
	}

	private static String next() throws IOException {
		while(!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	private static void file(String file) throws IOException {
		in = new BufferedReader(new FileReader(file+".in"));
		st = new StringTokenizer("");
		out = new PrintWriter(new BufferedWriter(new FileWriter(file+".out")));
	}

	private static void standart() {
		in = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer("");
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	}
}

import java.util.*;
public class Test {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] a = new long[] { in.nextInt(), in.nextInt(), in.nextInt() };
        Arrays.sort(a);
        System.out.println(Math.min((a[0] + a[1] + a[2]) / 3, a[0] + a[1]));
    }
}

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main
{
    public static void main(String[] args) throws IOException
    {
        Scanner scan = new Scanner(System.in);

        long n = scan.nextLong();
        long m = scan.nextLong();
        long k = scan.nextLong();
        if(n > 2*(m+k))
            n = 2*(m+k);
        if(m > 2*(n+k))
            m = 2*(n+k);
        if(k > 2*(n+m))
            k = 2*(n+m);

        System.out.println((n+m+k)/3);
    }
}

/*import java.io.BufferedReader;
        import java.io.InputStreamReader;

        public class TableDecoration {

        	public static long choose (int a){
        		if (a == 0)
        			return 0;
        		else {
        			long temp = a*(a-1)*(a-2)/6;
        			return temp;
        		}
        	}

        	public static void main(String[] args) throws Exception{
        		// TODO Auto-generated method stub

        		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        		String[] input = br.readLine().split(" ", 3);
        		int r = Integer.parseInt(input[0]);
        		int g = Integer.parseInt(input[1]);
        		int b = Integer.parseInt(input[2]);

        		int min = 999999999;
        		for ( int i =0; i< 3; i++){
        			if (Integer.parseInt(input[i])< min)
        				min = Integer.parseInt(input[i]);
        		}

        		long number =  min + choose(r+g+b - 3*min)- choose(r - min) - choose(g-min) - choose(b-min);

        		System.out.println(number);

        	}

        }*/

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

        public class TableDecoration {

        	public static void main(String[] args) throws Exception{
        		// TODO Auto-generated method stub

        		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        		String[] input = br.readLine().split(" ", 3);

        		long[] a = new long[3];
        		for(int i =0;i<3;i++)
        			a[i] = (long)Integer.parseInt(input[i]);

        		Arrays.sort(a);

        		long number = ((a[0]+a[1]+a[2])/3) < (a[0]+a[1]) ? (a[0]+a[1]+a[2])/3 : (a[0]+a[1]);

        		System.out.println(number);

        	}

        }

import java.util.*;import java.io.*;import java.math.*;
public class TableDecoration
{
    public static void process()throws IOException
    {
        long mod = 1;
        long[] a = nal(3);
        Arrays.sort(a);
        long ans = 0;
        if(a[2] >= 2*(a[0]+a[1]))
            ans = a[0] + a[1];
        else
            ans = (a[0] + a[1] + a[2])/3;
        pn(ans);
    }

    static AnotherReader sc;
    static PrintWriter out;
    public static void main(String[]args)throws IOException
    {
        boolean oj = System.getProperty("ONLINE_JUDGE") != null;
        if(oj){sc=new AnotherReader();out=new PrintWriter(System.out);}
        else{sc=new AnotherReader(100);out=new PrintWriter("output.txt");}
        int t=1;
        //t=ni();
        while(t-->0) {process();}
        out.flush();out.close();
    }

    static void pn(Object o){out.println(o);}
    static void p(Object o){out.print(o);}
    static void pni(Object o){out.println(o);out.flush();}
    static int ni()throws IOException{return sc.nextInt();}
    static long nl()throws IOException{return sc.nextLong();}
    static double nd()throws IOException{return sc.nextDouble();}
    static String nln()throws IOException{return sc.nextLine();}
    static int[] nai(int N)throws IOException{int[]A=new int[N];for(int i=0;i!=N;i++){A[i]=ni();}return A;}
    static long[] nal(int N)throws IOException{long[]A=new long[N];for(int i=0;i!=N;i++){A[i]=nl();}return A;}
    static long gcd(long a, long b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int gcd(int a, int b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int bit(long n)throws IOException{return (n==0)?0:(1+bit(n&(n-1)));}

/////////////////////////////////////////////////////////////////////////////////////////////////////////

    static class AnotherReader{BufferedReader br; StringTokenizer st;
    AnotherReader()throws FileNotFoundException{
    br=new BufferedReader(new InputStreamReader(System.in));}
    AnotherReader(int a)throws FileNotFoundException{
    br = new BufferedReader(new FileReader("input.txt"));}
    String next()throws IOException{
    while (st == null || !st.hasMoreElements()) {try{
    st = new StringTokenizer(br.readLine());}
    catch (IOException  e){ e.printStackTrace(); }}
    return st.nextToken(); } int nextInt() throws IOException{
    return Integer.parseInt(next());}
    long nextLong() throws IOException
    {return Long.parseLong(next());}
    double nextDouble()throws IOException { return Double.parseDouble(next()); }
    String nextLine() throws IOException{ String str = ""; try{
    str = br.readLine();} catch (IOException e){
    e.printStackTrace();} return str;}}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

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

public class TableDecorations {
    public static void main(String[]args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String [] in = br.readLine().split(" ");
        long r = Long.parseLong(in[0]);
        long g = Long.parseLong(in[1]);
        long b = Long.parseLong(in[2]);
        long [] arr = {r, g, b};
        Arrays.sort(arr);
        if (arr[2]/2 >= arr[0]+arr[1]) {
            System.out.println(arr[0]+arr[1]);
        } else {
            System.out.println((r+g+b)/3);
        }
    }
}

import java.util.*;
public class CF_478C
{
    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);
        long r = scan.nextLong();
        long g = scan.nextLong();
        long b = scan.nextLong();
        long[] sorted = {r, g, b};
        Arrays.sort(sorted);
        System.out.println(Math.min(((r+g+b)/3), sorted[0]+sorted[1]));
    }
}

import java.util.*;
public class c {
public static void main(String[] args)
{
    Scanner input = new Scanner(System.in);
    long a = input.nextInt(), b = input.nextInt(), c = input.nextInt();
    long min = Math.min(a, Math.min(b,c));
    long max = Math.max(a, Math.max(b, c));
    long other = a+b+c-min-max;
    long res = a+b+c;
    if(max > 2*(other + min)) res -= (max - 2*(other + min));
    System.out.println(res/3);
}
}

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		if (System.getProperty("ONLINE_JUDGE") == null) {
			inputStream = new FileInputStream("input.inp");
			// outputStream = new FileOutputStream("output.out");
		} else {
			inputStream = System.in;
			outputStream = System.out;
		}
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(in, out);
		out.close();
	}

	static final int N = 100005;
	static final int oo = 1000000007;
	static final double pi = Math.acos(-1);

	static class Task {
		public int get(int x, int y) {
			if (x <= 0 || y <= 0) return 0;
			return Math.min((x + y) / 3, x);
		}

		public void solve(InputReader in, PrintWriter out) {
			int[] a = new int[3];
			for (int i = 0; i < 3; ++i) a[i] = in.nextInt();
			long ans = 0;
			Arrays.sort(a);
			ans = Math.min(((long) a[0] + a[1] + a[2]) / 3, (long) a[0] + a[1]);
			out.print(ans);
		}
	}

	static 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 int nextInt() {
			return Integer.parseInt(next());
		}

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

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

		public char nextChar() {
			return next().charAt(0);
		}
	}
}

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

public class lvl_c_tableDecoration {

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

		String str=br.readLine();
		StringTokenizer st=new StringTokenizer(str);
		long[]a=new long[3];
		for(int i=0;i<3;i++) {
			a[i]=Long.parseLong(st.nextToken());
		}
		Arrays.sort(a);
		if(a[2]>=2*(a[0]+a[1]))
			System.out.println(a[0]+a[1]);
		else
			System.out.println((a[0]+a[1]+a[2])/3);

	}

}

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Arrays;
import java.util.Collections;

public class Problema1 {

	public static void main(String[] args) {

        Scanner reader = new Scanner(System.in);
        long red = reader.nextLong();
        long green = reader.nextLong();
        long blue = reader.nextLong();

        Long[] array = {red,green,blue} ;
        long output = 0;

        Arrays.sort (array, Collections.reverseOrder()) ;

        long parte1 = array[2];
        long parte2 = Math.min((array[0] + array[1] - 2 * parte1) / 3, array[1]);

        output = parte1 + parte2;
        System.out.println(output);

        reader.close();

	}

}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {
	static ArrayList<Edge> adj[];
	static PrintWriter out = new PrintWriter(System.out);
	public static long mod;

	static int [][]notmemo;
	static int k;
	static int a[];
	static int b[];
	static int m;
	static char c[];

	static class Pair implements Comparable<Pair>{
    	int x;
    	int y;
    	public Pair(int a,int b) {
		x=a;
		y=b;

    	}
		@Override
		public int compareTo(Pair o) {
			if(x!=o.x)
			return x-o.x;
			return y-o.y;
		}

    }
    static Pair s1[];
    static int s[];
    static ArrayList<Pair> adjlist[];
	private static HashSet<Integer> set1[];
	static int n1;
	static int n2;
	static int k1;
	static int k2;

	public static void main(String args[]) throws IOException {
		Scanner sc = new Scanner(System.in);
		long a[]=new long[3];
		a[0]=sc.nextInt();
		a[1]=sc.nextInt();
		a[2]=sc.nextInt();
		Arrays.sort(a);
		if(2*(a[0]+a[1])>a[2]) {
		System.out.println((a[0]+a[1]+a[2])/3);
		}
		else {
			System.out.println((a[0]+a[1]));
		}
	}
	static long dpdp[][][][];
	static int modd=(int) 1e8;
	static long dp(int i,int j,int counth,int countf) {

		if(k1<countf) {
			return 0;
		}
		if(k2<counth) {
			return 0;
		}
		if(i+j==n) {
			return 1;
		}
		if(dpdp[i][j][counth][countf]!=-1) {
			return dpdp[i][j][counth][countf];
		}
		long take1=0;
		long take2=0;
		if(i<n2)
		 take1=dp(i+1,j,counth+1,0)%modd;
		if(j<n1)
		take2=dp(i,j+1,0,countf+1)%modd;
		return  dpdp[i][j][counth][countf]=(take1%modd+take2%modd)%modd;

	}
    // with sum exactly equal to k.
    static int findSubarraySum(int arr[], int n, int sum)
    {
        // HashMap to store number of subarrays
        // starting from index zero having
        // particular value of sum.
        HashMap <Integer, Integer> prevSum = new HashMap<>();

        int res = 0;

        // Sum of elements so far.
        int currsum = 0;

        for (int i = 0; i < n; i++) {

            // Add current element to sum so far.
            currsum += arr[i];

            // If currsum is equal to desired sum,
            // then a new subarray is found. So
            // increase count of subarrays.
            if (currsum != 0)
                res++;

            // currsum exceeds given sum by currsum
            //  - sum. Find number of subarrays having
            // this sum and exclude those subarrays
            // from currsum by increasing count by
            // same amount.
            if (prevSum.containsKey(currsum - arr[i]))
                res += prevSum.get(currsum - arr[i]);

            // Add currsum value to count of
            // different values of sum.
            Integer count = prevSum.get(currsum);
            if (count == null)
                prevSum.put(currsum, 1);
            else
                prevSum.put(currsum, count+1);
        }

        return res;
    }
	public static int countvowels() {
		int count=0;
		for (int i = 0; i < c.length; i++) {
			if(c[i]=='o'||c[i]=='e'||c[i]=='a'||c[i]=='i'||c[i]=='u') {
				count++;
			}
		}
		return count;
	}
	public static  char lastvowel() {
		for (int i = c.length-1; i>=0; i--) {
			if(c[i]=='o'||c[i]=='e'||c[i]=='a'||c[i]=='i'||c[i]=='u') {
		return c[i];
			}
		}
		return 'a';
	}
	static class pp{
		String ss;
		String mm;
		public pp(String a,String b) {
		ss=a;
		mm=b;
		}
	}
	static class Tri implements Comparable<Tri>{
		String s;
		int numofvow;
		char lastchar;
	public	Tri(String m,int a,char c1){
			s=m;
			numofvow=a;
			lastchar=c1;

		}
	public int compareTo(Tri t) {
		if (numofvow == t.numofvow)
			return lastchar - t.lastchar;
		return numofvow - t.numofvow;
	}

	}
	static boolean dfs(int u, int cost) {
		boolean f=false;
		vis[u]=true;
		for(Edge p:adj[u]) {
			if(!vis[p.node]) {
				f|=dfs(p.node,(int) p.cost);
			}
		}
		if (cost == 2&&!f) {
				set.add(u + 1);
				return true;
		}
			return f;

	}
	static int min(int i,int last) {
		if(i==a.length)
			return 0;
		int take=0;
		if(gcd(a[i],last)>1||i==0) {
			take=Math.max(take,1+min(i+1,a[i]));
		}
	 take=Math.max(take,min(i+1,last));

		return b[i]=take;
	}

	private static boolean check(String s) {
		char c1[]=s.toCharArray();
		for (int i = 0; i < c1.length; i++) {
			if(c[i]>c1[i]) {
				return true;
			}
			 if(c[i]<c1[i])
				return false;
		}
		return true;
	}

	static long dijkstra(int S, int T)	//O(E log E)
	{
		long[] dist = new long[V];
		Arrays.fill(dist, (int) 1e9);
		PriorityQueue<Edge> pq = new PriorityQueue<Edge>();
		dist[S] = 0;
		pq.add(new Edge(S, 0));						//may add more in case of MSSP (Mult-Source)
		while(!pq.isEmpty())
		{
			Edge cur = pq.remove();
			if(cur.node == T)						//remove if all computations are needed
				return dist[T];
			if(cur.cost > dist[cur.node])			//lazy deletion
				continue;
			for(Edge nxt: adj[cur.node])
				if(cur.cost + nxt.cost < dist[nxt.node])
					pq.add(new Edge(nxt.node, dist[nxt.node] = cur.cost + nxt.cost ));
		}
		return -1;
	}
	static class Edge implements Comparable<Edge>
	{
		int node;long cost;

		Edge(int a, long b) { node = a;	cost = b; }

		public int compareTo(Edge e){ return Long.compare(cost,e.cost);	}
	}

    static int dp(int idx,int state) {
      if(idx==n) {
    	  return 0;
      }
      if(notmemo[idx][state]!=-1) {
    	  return notmemo[idx][state];
      }
     int take=0; int leave=0;int leaveall=0;
      if(a[idx]==1&&(state==1||state==0)) {
    	take=1+dp(idx+1,1);
      }
      if(a[idx]==0&&state==0) {
    	 leave=1+dp(idx+1,state);
      }
      leaveall=dp(idx+1,state);

      return notmemo[idx][state]=Math.max(take,Math.max(leaveall,leave));
    }
        static void sieve(int N)	// O(N log log N)
	{
		isComposite = new int[N+1];
		isComposite[0] = isComposite[1] = 1;			// 0 indicates a prime number
		primes = new ArrayList<Integer>();

		for (int i = 2; i <= N; ++i) 					//can loop till i*i <= N if primes array is not needed O(N log log sqrt(N))
			if (isComposite[i] == 0) 					//can loop in 2 and odd integers for slightly better performance
			{
				primes.add(i);
				if(1l * i * i <= N)
					for (int j = i * i; j <= N; j += i)	// j = i * 2 will not affect performance too much, may alter in modified sieve
						isComposite[j] = 1;
			}
	}
    static TreeSet<Integer> factors;
    static ArrayList<Integer> primeFactors(int N)		// O(sqrt(N) / ln sqrt(N))
	{
		ArrayList<Integer> factors = new ArrayList<Integer>();		//take abs(N) in case of -ve integers
		int idx = 0, p = primes.get(idx);

		while(1l*p * p <= N)
		{
			while(N % p == 0) { factors.add(p); N /= p; }
			p = primes.get(++idx);
		}

		if(N != 1)						// last prime factor may be > sqrt(N)
			factors.add(N);				// for integers whose largest prime factor has a power of 1
		return factors;
	}

    static String y;
    	static int nomnom[];
	static long fac[];

	static class book implements Comparable<book> {
		int idx;
		long score;

		public book(int i, long s) {
			idx = i;
			score = s;
		}

		public int compareTo(book o) {
			return (int) (o.score - score);
		}
	}

	static class library implements Comparable<library> {
		int numofbooks;
		int signup;
		int shiprate;
		int idx;

		public library(int a, int b, int c, int idx) {
			numofbooks = a;
			signup = b;
			shiprate = c;
			this.idx = idx;
		}

		@Override
		public int compareTo(library o) {
		if(signup==o.signup) {
			  return o.numofbooks-numofbooks;
		}
		return signup - o.signup;

		}
	}

	static boolean isOn(int S, int j) {
		return (S & 1 << j) != 0;
	}

	static boolean f = true;

	static class SegmentTree { // 1-based DS, OOP

		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;

		SegmentTree(int[] in) {
			array = in;
			N = in.length - 1;
			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N << 1];
			//build(1, 1, N);
		}

		void build(int node, int b, int e) // O(n)
		{
			if (b == e)
				sTree[node] = array[b];
			else {
				int mid = b + e >> 1;
				build(node << 1, b, mid);
				build(node << 1 | 1, mid + 1, e);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}
		}

		void update_point(int index, int val) // O(log n)
		{
			index += N - 1;
			sTree[index] = val;
			while(index>1)
			{
				index >>= 1;
				sTree[index] = Math.max(sTree[index<<1] ,sTree[index<<1|1]);
			}
		}

		void update_range(int i, int j, int val) // O(log n)
		{
			update_range(1, 1, N, i, j, val);
		}

		void update_range(int node, int b, int e, int i, int j, int val) {
			if (i > e || j < b)
				return;
			if (b >= i && e <= j) {
				sTree[node] += (e - b + 1) * val;
				lazy[node] += val;
			} else {
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node << 1, b, mid, i, j, val);
				update_range(node << 1 | 1, mid + 1, e, i, j, val);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}

		}

		void propagate(int node, int b, int mid, int e) {
			lazy[node << 1] += lazy[node];
			lazy[node << 1 | 1] += lazy[node];
			sTree[node << 1] += (mid - b + 1) * lazy[node];
			sTree[node << 1 | 1] += (e - mid) * lazy[node];
			lazy[node] = 0;
		}

		int query(int i, int j) {
			return query(1, 1, N, i, j);
		}

		int query(int node, int b, int e, int i, int j) // O(log n)
		{
			if (i > e || j < b)
				return 0;
			if (b >= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			// propagate(node, b, mid, e);
			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
			return Math.max(q1,q2);

		}
	}

	static int memo[];

	static class UnionFind {
		int[] p, rank, setSize;
		int numSets;
		int max[];

		public UnionFind(int N) {
			p = new int[numSets = N];
			rank = new int[N];
			setSize = new int[N];
			for (int i = 0; i < N; i++) {
				p[i] = i;
				setSize[i] = 1;
			}
		}

		public int findSet(int i) {
			return p[i] == i ? i : (p[i] = findSet(p[i]));
		}

		public boolean isSameSet(int i, int j) {
			return findSet(i) == findSet(j);
		}

		public void unionSet(int i, int j) {
			if (isSameSet(i, j))
				return;
			numSets--;
			int x = findSet(i), y = findSet(j);
			if (rank[x] > rank[y]) {
				p[y] = x;
				setSize[x] += setSize[y];

			} else {
				p[x] = y;
				setSize[y] += setSize[x];
				if (rank[x] == rank[y])
					rank[y]++;

			}
		}

		public int numDisjointSets() {
			return numSets;
		}

		public int sizeOfSet(int i) {
			return setSize[findSet(i)];
		}
	}

	/**
	 * private static void trace(int i, int time) { if(i==n) return;
	 *
	 *
	 * long ans=dp(i,time);
	 * if(time+a[i].t<a[i].burn&&(ans==dp(i+1,time+a[i].t)+a[i].cost)) {
	 *
	 * trace(i+1, time+a[i].t);
	 *
	 * l1.add(a[i].idx); return; } trace(i+1,time);
	 *
	 * }
	 **/

	static class incpair implements Comparable<incpair> {
		int a;
		long b;
		int idx;

		incpair(int a, long dirg, int i) {
			this.a = a;
			b = dirg;
			idx = i;
		}

		public int compareTo(incpair e) {
			return (int) (b - e.b);
		}
	}

	static class decpair implements Comparable<decpair> {
		int a;
		long b;
		int idx;

		decpair(int a, long dirg, int i) {
			this.a = a;
			b = dirg;
			idx = i;
		}

		public int compareTo(decpair e) {
			return (int) (e.b - b);
		}
	}

	static long allpowers[];

	static class Quad implements Comparable<Quad> {
		int u;
		int v;
		char state;
		int turns;

		public Quad(int i, int j, char c, int k) {
			u = i;
			v = j;
			state = c;
			turns = k;
		}

		public int compareTo(Quad e) {
			return (int) (turns - e.turns);
		}

	}

	static long dirg[][];
	static Edge[] driver;

	static int n;

	static long manhatandistance(long x, long x2, long y, long y2) {
		return Math.abs(x - x2) + Math.abs(y - y2);
	}

	static long fib[];

	static long fib(int n) {
		if (n == 1 || n == 0) {
			return 1;
		}
		if (fib[n] != -1) {
			return fib[n];
		} else
			return fib[n] = ((fib(n - 2) % mod + fib(n - 1) % mod) % mod);
	}

	static class Point  implements Comparable<Point>{
		long x, y;

		Point(long counth, long counts) {
			x = counth;
			y = counts;
		}

		@Override
		public int compareTo(Point p )
		{
			return Long.compare(p.y*1l*x, p.x*1l*y);
		}

	}

	static long[][] comb;

	static class Triple implements Comparable<Triple> {

		int l;
		int r;
		long cost;
		int idx;

		public Triple(int a, int b, long l1, int l2) {
			l = a;
			r = b;
			cost = l1;
			idx = l2;
		}

		public int compareTo(Triple x) {
			if (l != x.l || idx == x.idx)
				return l - x.l;
			return -idx;
		}

	}

	static TreeSet<Long> primeFactors(long N) // O(sqrt(N) / ln sqrt(N))
	{
		TreeSet<Long> factors = new TreeSet<Long>(); // take abs(N) in case of -ve integers
		int idx = 0, p = primes.get(idx);

		while (p * p <= N) {
			while (N % p == 0) {
				factors.add((long) p);
				N /= p;
			}
			if (primes.size() > idx + 1)
				p = primes.get(++idx);
			else
				break;
		}

		if (N != 1) // last prime factor may be > sqrt(N)
			factors.add(N); // for integers whose largest prime factor has a power of 1
		return factors;
	}

	static boolean visited[];

	/**
	 * static int bfs(int s) { Queue<Integer> q = new LinkedList<Integer>();
	 * q.add(s); int count=0; int maxcost=0; int dist[]=new int[n]; dist[s]=0;
	 * while(!q.isEmpty()) {
	 *
	 * int u = q.remove(); if(dist[u]==k) { break; } for(Pair v: adj[u]) {
	 * maxcost=Math.max(maxcost, v.cost);
	 *
	 *
	 *
	 * if(!visited[v.v]) {
	 *
	 * visited[v.v]=true; q.add(v.v); dist[v.v]=dist[u]+1; maxcost=Math.max(maxcost,
	 * v.cost); } }
	 *
	 * } return maxcost; }
	 **/
	public static boolean FindAllElements(int n, int k) {
		int sum = k;
		int[] A = new int[k];
		Arrays.fill(A, 0, k, 1);

		for (int i = k - 1; i >= 0; --i) {

			while (sum + A[i] <= n) {

				sum += A[i];
				A[i] *= 2;
			}
		}
		if (sum == n) {
			return true;
		} else
			return false;
	}

	static boolean[] vis2;

	static boolean f2 = false;

	static long[][] matMul(long[][] a2, long[][] b, int p, int q, int r) // C(p x r) = A(p x q) x (q x r) -- O(p x q x
																			// r)
	{
		long[][] C = new long[p][r];
		for (int i = 0; i < p; ++i) {
			for (int j = 0; j < r; ++j) {
				for (int k = 0; k < q; ++k) {
					C[i][j] = (C[i][j] + (a2[i][k] % mod * b[k][j] % mod)) % mod;
					C[i][j] %= mod;
				}

			}
		}
		return C;
	}

	static int memo1[];

	static boolean vis[];
	static TreeSet<Integer> set = new TreeSet<Integer>();

	static long modPow(long ways, long count, long mod) // O(log e)
	{
		ways %= mod;
		long res = 1;
		while (count > 0) {
			if ((count & 1) == 1)
				res = (res * ways) % mod;
			ways = (ways * ways) % mod;
			count >>= 1;
		}
		return res % mod;
	}

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

	static int[] isComposite;
	static int[] valid;

	static ArrayList<Integer> primes;
	static ArrayList<Integer> l1;

	static TreeSet<Integer> primus = new TreeSet<Integer>();

	static void sieveLinear(int N)
	{
		int[] lp = new int[N + 1];								//lp[i] = least prime divisor of i
		for(int i = 2; i <= N; ++i)
		{
			if(lp[i] == 0)
			{
				primus.add(i);
				lp[i] = i;
			}
			int curLP = lp[i];
			for(int p: primus)
				if(p > curLP || p * i > N)
					break;
				else
					lp[p * i] = i;
		}
	}

	public static int[] schuffle(int[] p) {
		for (int i = 0; i < p.length; i++) {
			int x = (int) (Math.random() * p.length);
			int temp = p[x];
			p[x] = p[i];
			p[i] = temp;
		}
		return p;
	}

	static int V;
	static long INF = (long) 1E16;

	static class Edge2 {
		int node;
		long cost;
		long next;

		Edge2(int a, int c, Long long1) {
			node = a;
			cost = long1;
			next = c;
		}

	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

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

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

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

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

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

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

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

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

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

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}

		public int[] nxtArr(int n) throws IOException {
			int[] ans = new int[n];
			for (int i = 0; i < n; i++)
				ans[i] = nextInt();
			return ans;
		}
	}
}

import java.util.*;

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

public class TableDecorations478C {
    static void go() {
        long total = 0;
        long[] c = new long[3];
        for(int i = 0; i < 3; i++) {
            c[i] = in.nextLong();
            total += c[i];
        }

        Arrays.sort(c);
        long max = total / 3;
        if (c[0] + c[1] >= max) {
            out.println(max);
        } else {
            out.println(c[0]+c[1]);
        }
    }

    static InputReader in;
    static PrintWriter out;

    public static void main(String[] args) {
        in = new InputReader(System.in);
        out = new PrintWriter(System.out);

        go();

        out.close();
    }

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

        public InputReader(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++];
        }

        public int[] nextIntArray(int len) {
            int[] ret = new int[len];
            for (int i = 0; i < len; i++)
                ret[i] = nextInt();
            return ret;
        }

        public long[] nextLongArray(int len) {
            long[] ret = new long[len];
            for (int i = 0; i < len; i++)
                ret[i] = nextLong();
            return ret;
        }

        public int nextInt() {
            return (int) nextLong();
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public String nextString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder sb = new StringBuilder(1024);
            do {
                sb.append((char) c);
                c = read();
            } while (!isSpaceChar(c));
            return sb.toString();
        }

        public static boolean isSpaceChar(int c) {
            switch (c) {
                case -1:
                case ' ':
                case '\n':
                case '\r':
                case '\t':
                    return true;
                default:
                    return false;
            }
        }
    }
}

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

public class Main {

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

	public static void A() {
		int s = 0;
		for (int index = 0; index < 5; ++index) {
			s += IO.readInt();
		}

		if (s > 0 && s % 5 == 0) {
			IO.println(s / 5);
		}
		else {
			IO.println(-1);
		}

	}

	public static void B() {
		long n = IO.readLong();
		long m = IO.readLong();

		long size = n / m;

		long kmin = pairs(size) * (m - (n - size * m)) + pairs(size + 1) * (n - size * m);
		long kmax = pairs(n - m + 1);

		IO.println(kmin + " " + kmax);
	}

	private static long pairs(long n) {
		return n * (n - 1) / 2;
	}

	public static void C() {
		long[] a = new long[3];
		for (int index = 0; index < 3; ++index) {
			a[index] = IO.readLong();
		}

		Arrays.sort(a);

		long ans = 0;
		if (a[2] >= (a[0] + a[1]) * 2) {
			ans = a[0] + a[1];
		}
		else {
			ans = (a[0] + a[1] + a[2]) / 3;
		}

		IO.println(ans);
	}

	public static void D() {

	}

	public static void E() {

	}

	//************* Input/Output *************//

	private static class IO {
		static {
			setUpScanner();
		}

		private static Scanner scanner;

		private static void setUpScanner() {
			scanner = new Scanner(new java.io.BufferedInputStream(System.in));
		};

		public static boolean isEmpty() {
			return !scanner.hasNext();
		}

		public static boolean hasNextLine() {
			return scanner.hasNextLine();
		}

		public static String readLine() {
			String line;
			try {
				line = scanner.nextLine();
			} catch (Exception e) {
				line = null;
			}
			return line;
		}

		public static String readString() {
			return scanner.next();
		}

		public static int readInt() {
			return scanner.nextInt();
		}

		public static double readDouble() {
			return scanner.nextDouble();
		}

		public static float readFloat() {
			return scanner.nextFloat();
		}

		public static long readLong() {
			return scanner.nextLong();
		}

		public static void print(Object o) {
			System.out.print(o.toString());
		}

		public static void println(Object o) {
			System.out.println(o);
		}
	}

	//************* Algorithms *************//

	private static class Algo {

		public static int binSearch(int[] array, int n, int lo, int hi) {
			if (lo > hi) {
				return lo;
			}

			int mid = lo + (hi - lo) /2;
			int cmp = (int) Math.signum(n - array[mid]);
			if (cmp < 0) {
				return binSearch(array, n, lo, mid - 1);
			}
			else if (cmp == 0) {
				return mid;
			}
			else {
				return binSearch(array, n, mid + 1, hi);
			}
		}

	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, Scanner in, PrintWriter out) {
            long[] arr = new long[3];
            for (int i = 0; i < 3; i++)
                arr[i] = in.nextLong();
            Arrays.sort(arr);
            long a = arr[0];
            long b = arr[1];
            long c = arr[2];
            long req = (c - b) / 2;
            if (req < a) {
                c -= 2 * req;
                b -= (a - req);
                c -= (a - req);
            } else {
                c -= 2 * a;
            }
            long rem = (b + c) / 3;
            long ans = a;
            ans += Math.min(rem, Math.min(b, c));
            out.println(ans);
        }

    }
}

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

public class Main{
    public static void main (String[] args) throws java.lang.Exception{
        //BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        InputReader in=new InputReader(System.in);
        PrintWriter out=new PrintWriter(System.out);
        int r=in.readInt();
        int g=in.readInt();
        int b=in.readInt();
        long[] a={r,g,b};Arrays.sort(a);
        long ans=Math.min((a[0]+a[1]+a[2])/3,a[0]+a[1]);
        out.println(ans);
        out.close();
    }
    static final class InputReader{
        private final InputStream stream;
        private final byte[] buf=new byte[1024];
        private int curChar;
        private int numChars;
        public InputReader(InputStream stream){this.stream=stream;}
        private int read()throws IOException{
            if(curChar>=numChars){
                curChar=0;
                numChars=stream.read(buf);
                if(numChars<=0)
                    return -1;
            }
            return buf[curChar++];
        }
        public final int readInt()throws IOException{return (int)readLong();}
        public final long readLong()throws IOException{
            int c=read();
            while(isSpaceChar(c)){
                c=read();
                if(c==-1) throw new IOException();
            }
            boolean negative=false;
            if(c=='-'){
                negative=true;
                c=read();
            }
            long res=0;
            do{
                if(c<'0'||c>'9')throw new InputMismatchException();
                res*=10;
                res+=(c-'0');
                c=read();
            }while(!isSpaceChar(c));
            return negative?(-res):(res);
        }
        public final int[] readIntBrray(int size)throws IOException{
            int[] arr=new int[size];
            for(int i=0;i<size;i++)arr[i]=readInt();
            return arr;
        }
        public final String readString()throws IOException{
            int c=read();
            while(isSpaceChar(c))c=read();
            StringBuilder res=new StringBuilder();
            do{
                res.append((char)c);
                c=read();
            }while(!isSpaceChar(c));
            return res.toString();
        }
        public final String readLine()throws IOException{
            int c=read();
            while(isSpaceChar(c))c=read();
            StringBuilder res=new StringBuilder();
            do{
                res.append((char)c);
                c=read();
            }while(!isSpaceChar(c));
            return res.toString();
        }
        private boolean isSpaceChar(int c){
            return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
        }
    }
}

import java.util.*;
import java.util.Scanner;
import java.io.*;
import javax.lang.model.util.ElementScanner6;
import static java.lang.System.out;

public class C478
{

    public static void main(String args[])
    {

        FastReader in=new FastReader();
        PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        int tc=1;

        //tc=in.nextInt();
        while(tc-->0)
        {

        	long col[]=new long[3];
        	col[0]=in.nextLong();
        	col[1]=in.nextLong();
        	col[2]=in.nextLong();

			long sum=col[0]+col[1]+col[2];

			sort(col);

			long second=col[1]+col[0];

			second=Math.min(second,col[2]);

			pr.println(Math.min(second,sum/3));

        }
        pr.flush();
    }

    static void sort(long[] a) {
		ArrayList<Long> l = new ArrayList<>();
		for (long i : a)
			l.add(i);
		Collections.sort(l);
		for (int i = 0; i < a.length; i++)
			a[i] = l.get(i);
	}

	static void sort(int[] a) {
		ArrayList<Integer> l = new ArrayList<>();
		for (int i : a)
			l.add(i);
		Collections.sort(l);
		for (int i = 0; i < a.length; i++)
			a[i] = l.get(i);
    }

    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            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;
        }
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Solution{

    ///////////////////////////////////////////////////////////////////////////
    static class FastScanner{
        BufferedReader s;
        StringTokenizer st;

        public FastScanner(InputStream InputStream){
            st = new StringTokenizer("");
            s = new BufferedReader(new InputStreamReader(InputStream));
        }

        public FastScanner(File f) throws FileNotFoundException{
            st = new StringTokenizer("");
            s = new BufferedReader (new FileReader(f));
        }

        public int nextInt() throws IOException{
            if(st.hasMoreTokens())
                return Integer.parseInt(st.nextToken());
            else{
                st = new StringTokenizer(s.readLine());
                return nextInt();
            }
        }

        public BigInteger big() throws IOException{
            if(st.hasMoreTokens())
                return new BigInteger(st.nextToken());
            else{
                st = new StringTokenizer(s.readLine());
                return big();
            }
        }

        public double nextDouble() throws IOException{
            if(st.hasMoreTokens())
                return Double.parseDouble(st.nextToken());
            else{
                st = new StringTokenizer(s.readLine());
                return nextDouble();
            }
        }

        public long nextLong() throws IOException{
            if(st.hasMoreTokens())
                return Long.parseLong(st.nextToken());
            else{
                st = new StringTokenizer(s.readLine());
                return nextLong();
            }
        }

        public String nextString() throws IOException{
            if(st.hasMoreTokens())
                return st.nextToken();
            else{
                st = new StringTokenizer(s.readLine());
                return nextString();
            }

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

        public void close() throws IOException{
            s.close();
        }

    }

    ////////////////////////////////////////////////////////////////////
    //      Number Theory

    long pow(long a,long b,long mod){
        long x = 1; long y = a;
        while(b > 0){
            if(b % 2 == 1){
                x = (x*y);
                x %= mod;
            }
            y = (y*y);
            y %= mod;
            b /= 2;
        }
        return x;
    }

    int divisor(long x,long[] a){
        long limit = x;
        int numberOfDivisors = 0;

        for (int i=1; i < limit; ++i) {
            if (x % i == 0) {
                limit = x / i;
                if (limit != i) {
                    numberOfDivisors++;
                }
                numberOfDivisors++;
            }
        }
        return numberOfDivisors;
    }

    void findSubsets(int array[]){
        long numOfSubsets = 1 << array.length;
        for(int i = 0; i < numOfSubsets; i++){
            @SuppressWarnings("unused")
            int pos = array.length - 1;
            int bitmask = i;
            while(bitmask > 0){
                if((bitmask & 1) == 1)
//                    ww.print(array[pos]+" ");
                bitmask >>= 1;
                pos--;
            }
//            ww.println();
        }
    }

    public static long gcd(long a, long b){
        return b == 0 ? a : gcd(b,a%b);
    }

    public static int lcm(int a,int b, int c){
        return lcm(lcm(a,b),c);
    }

    public static int lcm(int a, int b){
        return (int) (a*b/gcd(a,b));
    }

    public static long invl(long a, long mod) {
        long b = mod;
        long p = 1, q = 0;
        while (b > 0) {
            long c = a / b;
            long d;
            d = a;
            a = b;
            b = d % b;
            d = p;
            p = q;
            q = d - c * q;
        }
        return p < 0 ? p + mod : p;
    }

    ////////////////////////////////////////////////////////////////////

//    FastScanner s = new FastScanner(new File("input.txt"));
//    PrintWriter ww = new PrintWriter(new FileWriter("output.txt"));
    static InputStream inputStream = System.in;
    static FastScanner s = new FastScanner(inputStream);
    static OutputStream outputStream = System.out;
    static PrintWriter ww = new PrintWriter(new OutputStreamWriter(outputStream));
//      private static Scanner s = new Scanner(System.in);
    @SuppressWarnings("unused")
    private static int[][] states = { {-1,0} , {1,0} , {0,-1} , {0,1} };

    ////////////////////////////////////////////////////////////////////

    public static void main(String[] args) throws IOException{
        new Solution().solve();
        s.close();
        ww.close();
    }

    ////////////////////////////////////////////////////////////////////

    void solve() throws IOException{

        long a[] = new long [3];
        for (int i = 0; i < 3; i++)
            a[i] = s.nextInt();

        Arrays.sort(a);
        if(2 * (a[0] + a[1]) <= a[2])
            a[2] = 2 * (a[0] + a[1]);

        ww.println((a[0]+a[1]+a[2])/3);

    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.FilterInputStream;
import java.io.BufferedInputStream;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Jenish
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        ScanReader in = new ScanReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, ScanReader in, PrintWriter out) {
            long arr[] = new long[3];
            arr[0] = in.scanInt();
            arr[1] = in.scanInt();
            arr[2] = in.scanInt();
            Arrays.sort(arr);
            long ans = arr[0] + arr[1];
            if (ans * 2 >= arr[2]) {
                out.println((ans + arr[2]) / 3);
            } else {
                out.println(ans);
            }
        }

    }

    static class ScanReader {
        private byte[] buf = new byte[4 * 1024];
        private int INDEX;
        private BufferedInputStream in;
        private int TOTAL;

        public ScanReader(InputStream inputStream) {
            in = new BufferedInputStream(inputStream);
        }

        private int scan() {
            if (INDEX >= TOTAL) {
                INDEX = 0;
                try {
                    TOTAL = in.read(buf);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                if (TOTAL <= 0) return -1;
            }
            return buf[INDEX++];
        }

        public int scanInt() {
            int I = 0;
            int n = scan();
            while (isWhiteSpace(n)) n = scan();
            int neg = 1;
            if (n == '-') {
                neg = -1;
                n = scan();
            }
            while (!isWhiteSpace(n)) {
                if (n >= '0' && n <= '9') {
                    I *= 10;
                    I += n - '0';
                    n = scan();
                }
            }
            return neg * I;
        }

        private boolean isWhiteSpace(int n) {
            if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
            else return false;
        }

    }
}

import java.util.*;
public class Main
{
	public static void main(String[] args) {

        Scanner s = new Scanner(System.in);
        long bal[] = new long[3];
        bal[0] = s.nextLong();
        bal[1] = s.nextLong();
        bal[2] = s.nextLong();
        long res = (bal[0]+bal[1]+bal[2])/3;
        Arrays.sort(bal);
        if((bal[0] + bal[1])<res)
            res = bal[0]+bal[1];
        System.out.println(res);
    }
}

import java.util.*;
import java.io.*;
public class Prac {
	static Map<Integer, Integer>[] gr;
	static int[] par;
	static boolean[] in;
	static long[] dis;

	public static void main(String[] args){
		FastReader sc=new FastReader();
		PrintStream ps=System.out;

		int r=sc.nextInt(), g=sc.nextInt(), b=sc.nextInt();
		int[] ar=new int[]{r, g, b};
		Arrays.sort(ar);

		int ans=Math.min(ar[1]-ar[0],(ar[2]-ar[1])/2);
		ar[1]-=ans;
		ar[2]-=2*ans;

		int d=Math.min(ar[0], (ar[2]-ar[1])/3);
		ans+=2*d;
		ar[0]-=d;ar[1]-=d;ar[2]-=4*d;

		d=ar[0]-ar[0]%2;
		ans+=d;
		ar[0]-=d;ar[1]-=d;ar[2]-=d;

		if(ar[0]==1){
			if(ar[2]>1){
				ar[0]--;ar[2]-=2;
			}else{
				ar[0]--;ar[1]--;ar[2]--;
			}
			ans++;
		}

		Arrays.sort(ar);
		int x=ar[1], y=ar[2];
		d=Math.min(y-x, Math.min(x, y/2));
		ans+=d;
		x-=d;
		y-=2*d;

		if(x!=0) ans+=(x+y)/3;
		ps.println(ans);

	}

	public static void dfs(int v, int m, long dist, long min) {
		in[v]=true;

		if(v!=m && dist<min) {
			Set<Map.Entry<Integer, Integer>> set=gr[v].entrySet();

			for(Map.Entry<Integer, Integer> e: set){
				int nv=e.getKey(), w=e.getValue();
				if(!in[nv]){
					dfs(nv, m, dist+w, min);
					min=Math.min(min-w-dist, dis[nv])+w+dist;
					if(dis[v]-w>dis[nv]){
						par[nv]=v;
						dis[v]=dis[nv]+w;
					}
				}
			}
		}
		in[v]=false;
	}
}

class FastReader  {
    BufferedReader br;
    StringTokenizer st;

    public FastReader()
    {
        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;
    }
}

import java.util.*;
public class Main
{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long A[]=new long[3];
		for(int i=0;i<3;i++){
		    A[i]=sc.nextLong();
		}
		Arrays.sort(A);
		long m = A[0]+A[1];
		if(A[2]<m*2){
		    System.out.println((m+A[2])/3);
		}else{
		    System.out.println(m);
		}

	}
}

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

/**
 * Created by msi on 4/2/2017.
 */
public class TableDecorations2 {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] colors = new long[3];
        colors[0] = in.nextInt();
        colors[1] = in.nextInt();
        colors[2] = in.nextInt();

        Arrays.sort(colors);
        if ((colors[0] + colors[1]) * 2 <= colors[2]) {
            System.out.println(colors[0] + colors[1]);
        } else {
            System.out.println((colors[0] + colors[1] + colors[2]) / 3);
        }

    }
}

import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Task478C {

    public static void main(String... args) throws NumberFormatException,
            IOException {
        Solution.main(System.in, System.out);
    }

    static class Scanner {

        private final BufferedReader br;
        private String[] cache;
        private int cacheIndex;

        Scanner(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
            cache = new String[0];
            cacheIndex = 0;
        }

        int nextInt() throws IOException {
            if (cacheIndex >= cache.length) {
                cache = br.readLine().split(" ");
                cacheIndex = 0;
            }
            return Integer.parseInt(cache[cacheIndex++]);
        }

        long nextLong() throws IOException {
            if (cacheIndex >= cache.length) {
                cache = br.readLine().split(" ");
                cacheIndex = 0;
            }
            return Long.parseLong(cache[cacheIndex++]);
        }

        String next() throws IOException {
            if (cacheIndex >= cache.length) {
                cache = br.readLine().split(" ");
                cacheIndex = 0;
            }
            return cache[cacheIndex++];
        }

        void close() throws IOException {
            br.close();
        }

    }

    static class Solution {

        public static void main(InputStream is, OutputStream os)
                throws NumberFormatException, IOException {
            PrintWriter pw = new PrintWriter(os);
            Scanner sc = new Scanner(is);

            ArrayList<Long> a = new ArrayList<Long>(3);

    a.add(sc.nextLong());
    a.add(sc.nextLong());
    a.add(sc.nextLong());

            Collections.sort(a);

            if(a.get(2) > (a.get(0) + a.get(1)) * 2){
                pw.println(a.get(0) + a.get(1));
            }else{
                pw.println((a.get(0) + a.get(1) + a.get(2))/3);
            }

            pw.flush();
            sc.close();
        }
    }

}

import java.util.*;

public class temp {

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int r = s.nextInt();
		int g = s.nextInt();
		int b = s.nextInt();
		int ans = solveme(largest(r,g,b),middle(r,g,b),smallest(r,g,b));
		//System.out.println(r);
		System.out.println(ans);
	}
	public static int largest(int a, int b, int c) {
	  return Integer.max(a, Integer.max(b, c));
	}
	public static int smallest(int a, int b, int c) {
	  return Integer.min(a, Integer.min(c, b));
	}
	public static int middle(int a, int b, int c) {
	  return largest(Integer.min(a, b), Integer.min(c, b), Integer.min(a, c));
	}

	public static int solveme(int max, int mid, int min) {

	  if (max==min)
	    return max;
	  else if (Long.valueOf(mid) + Long.valueOf(max) < 3 || mid == 0)
	    return 0;
	  else if (max-min==1)
      return min;

	  else if (mid==min) {
	    int count = (max - mid)/3;
	    int half = 0;
	    if ((max-mid)%3==2)
	      half++;
	    if (min*2>2*count+half) {
  	    max = max-(4*count)-(2*half);
  	    mid = mid - (count+half);
  	    min = min-count;
  	    return solveme(largest(max, mid, min), middle(max, mid, min), smallest(max, mid, min)) + count*2 + half;
	    }
	    else {
	      return 2*min;
	    }
	  }
	  else if (max==mid) {
      int count = (max-min)/3;
      if ((max-min)%3==2)
        count++;
      max = max-(3*count);
      mid = max;
      return solveme(largest(max, mid, min), middle(max, mid, min), smallest(max, mid, min)) + count*2;
    }

	  else if (max-mid>=mid-min) {
      int count = mid - min;
      mid = min;
      max = max - count*2;
      return solveme(largest(max, mid, min), middle(max, mid, min), smallest(max, mid, min)) + count;
    }
    else if (max-mid<mid-min){
      int count = max - mid;
      mid = mid - count;
      max = mid;
      return solveme(largest(max, mid, min), middle(max, mid, min), smallest(max, mid, min)) + count;
    }

	  else {
	    max = max - 2;
	    mid--;
	    return solveme(largest(max, mid, min), middle(max, mid, min), smallest(max, mid, min)) + 1;
	  }
	}
}

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

public class TableDecorations
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int[] a =
        { in.nextInt(), in.nextInt(), in.nextInt() };
        Arrays.sort(a);
        if ((0l + a[0] + a[1]) <= a[2] / 2 )
            System.out.println(a[0] + a[1]);
        else
            System.out.println((0l + a[0] + a[1] + a[2]) / 3);
        in.close();
    }
}

import java.util.List;
import java.util.Scanner;
import java.util.Comparator;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Noord
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Scanner in = new Scanner(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        ArrayList<Long> l = new ArrayList<Long>();
        l.add(in.nextLong());
        l.add(in.nextLong());
        l.add(in.nextLong());

        Collections.sort(l,Collections.reverseOrder());

        if(l.get(0) > (l.get(1) + l.get(2))*2)
            out.write(l.get(1)+l.get(2) + "");
        else
            out.write( (l.get(0) + l.get(1)+ l.get(2)) /3 + "");
    }
}

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

public class TableDecorations {

    public static void main(String[] args) throws IOException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));
        String[] strings = reader.readLine().split(" ");
        long[] is = new long[3];
        int index = 0;
        for (String string : strings) {
            is[index++] = Long.valueOf(string);
        }
        Arrays.sort(is);
        long sum = 0;
        if ((is[2] / 2) >= (is[0] + is[1])) {
            sum += is[0] + is[1];
        } else {
            for (long i : is) {
                sum += i;
            }
            sum /= 3;
        }
        System.out.println(sum);
    }
}

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

public class Main {

    public static void main(String[] args) throws Exception {
        long startTime = System.nanoTime();
        long [] data = new long[3];

        for (int i = 0; i < 3; i++) {
            data[i]=in.nextLong();
        }
        out.println(f(data));
        long endTime = System.nanoTime();
        err.println("Execution Time : +" + (endTime - startTime) / 1000000 + " ms");
        exit(0);
    }

    static int [] getRandomArray(int n,int LIM) {
        Random r = new Random();
        int [] data = new int[n];
        for (int i = 0; i < n; i++)
            data[i] = r.nextInt(LIM);
        return data;
    }

    static long f(long [] data) {
        Arrays.sort(data);
        long ans = 0;
        data[1] += data[0];
        data[0]-=data[0];
        Arrays.sort(data);
        long diff = data[2] - data[1];
        if (diff >= data[1] && data[2] >= 2 && data[1] >= 1) {
            ans += data[1];
        } else if (diff < data[1] && data[2] >= 2 && data[1] >= 1) {
            ans += diff;
            data[1] -= diff;
            data[2] -= diff * 2;
            ans += (data[2] + data[1]) / 3;
        }
        return ans;
    }

    static 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 long nextLong() {
            return Long.parseLong(next());
        }

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

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

    static void exit(int a) {
        out.close();
        err.close();
        System.exit(a);
    }

    static InputStream inputStream = System.in;
    static OutputStream outputStream = System.out;
    static OutputStream errStream = System.err;
    static InputReader in = new InputReader(inputStream);
    static PrintWriter out = new PrintWriter(outputStream);
    static PrintWriter err = new PrintWriter(errStream);
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

}

import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;

public class C274 {
    public static void main(String[] args) {
        Scanner kb = new Scanner(System.in);
        ArrayList<Long> colors = new ArrayList<Long>();
        colors.add(kb.nextLong());
        colors.add(kb.nextLong());
        colors.add(kb.nextLong());
        Collections.sort(colors);
        if( (colors.get(0)+colors.get(1))*2<colors.get(2)){
            System.out.println(colors.get(0)+colors.get(1));
        } else {
            System.out.println( (colors.get(0)+colors.get(1)+colors.get(2))/3);
        }
    }
}

import java.io.*;
import java.util.*;
public class ppp3
{
    public static void main(String[] args) throws IOException
    {
    	Scanner f = new Scanner(System.in);
        StringTokenizer st = new StringTokenizer(f.nextLine());
        long r = Integer.parseInt(st.nextToken());
        long g = Integer.parseInt(st.nextToken());
        long b = Integer.parseInt(st.nextToken());
        f.close();

        long x, y, z;
        if(r<g){
        	if(r<b){
        		x = r;
        		if(g < b){
        			y = g;
        			z = b;
        		}
        		else{
        			y = b;
        			z = g;
        		}
        	}
        	else{
        		x = b;
        		y = r;
        		z = g;
        	}
        }
        else{
        	if(g<b){
        		x = g;
        		if( r>b){
        			y = b;
        			z = r;
        		}
        		else{
        			y = r;
        			z = b;
        		}
        	}
        	else{
        		 x = b;
        		 y = g;
        		 z = r;
        	}
        }
        //System.out.println(x + " " + y + " " + z);

        if(2*(x + y)<=z){
        	System.out.println(x+y);
        }
        else{
        	System.out.println(((x+y+z)/3));
        }

    }
}

import java.util.*;
import java.io.*;
public class table_decorations {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long a[] = new long[3];
		a[0] = sc.nextLong();
		a[1] = sc.nextLong();
		a[2] = sc.nextLong();

		Arrays.sort(a);
		if(a[0]+a[1] <= a[2]/2) {
			System.out.println(a[0]+a[1]);
		}
		else {
			System.out.println((a[0]+a[1]+a[2])/3);
		}

	}

}

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

public class Main {
  // main
  public static void main(String [] args) throws IOException {
    // makes the reader and writer
    BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

    // read in
    int[] nums = new int[3];
    StringTokenizer st = new StringTokenizer(f.readLine());
    for (int i=0;i<3;i++) nums[i] = Integer.parseInt(st.nextToken());
    Arrays.sort(nums);

    // write to out
    out.println(Math.min(((long) nums[0]+nums[1]+nums[2])/3,(long) nums[0]+nums[1]));

    // cleanup
    out.close();
    System.exit(0);
  }
}

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

public class Repetition {
	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer tok;

	public static void main(String[] args) throws IOException {
		in = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(new OutputStreamWriter(System.out));
		tok = new StringTokenizer("");
		new Repetition().solve();
		out.flush();
		out.close();
	}

	String nextTok() throws IOException {
		if (!tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

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

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

	long colors[];
	void solve() throws IOException {
		colors = new long[3];
		colors[0] = nextLong();
		colors[1] = nextLong();
		colors[2] = nextLong();
		Arrays.sort(colors);
		if (colors[2] >= (colors[0]+colors[1])*2L) {
			out.println(colors[0]+colors[1]);
		} else out.println((colors[0]+colors[1]+colors[2])/3L);

	}

}

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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Reader in = new Reader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, Reader in, PrintWriter out) {
            int[] balls = new int[3];
            for (int i = 0; i < 3; ++i)
                balls[i] = in.nextInt();

            Arrays.sort(balls);
            long res = balls[0];

            for (int i = 0; i < 3; ++i)
                balls[i] -= res;

            if (balls[1] == 0) {
                out.println(res);
                return;
            }

            res += getres(balls[1], balls[2]);
            out.println(res);
        }

        int getres(int a, int b) {
            if (a * 2 <= b) return a;

            int maxdouble = 0;
            int maxsingle = 0;
            int max = 0;
            int res = 0;

            maxdouble = b / 2;
            maxsingle = a;

            max = Math.min(maxsingle, maxdouble);

            res += max;

            a -= max;
            b -= 2 * max;

            return res + Math.min(Math.max(a, b), res) / 3;
        }

    }

    static class Reader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public Reader(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 int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

import java.util.*;
import java.io.*;
public class Table_Decorations
{
	public static void main(String args[]) throws Exception
	{
		BufferedReader f=new BufferedReader(new InputStreamReader(System.in));
		// BufferedReader f=new BufferedReader(new FileReader("Table_Decorations.in"));
		StringTokenizer st=new StringTokenizer(f.readLine());
		int one=Integer.parseInt(st.nextToken());
		int two=Integer.parseInt(st.nextToken());
		int three=Integer.parseInt(st.nextToken());
		int ans=Math.min(one,Math.min(two,three));
		one-=ans;
		two-=ans;
		three-=ans;
		int max=Math.max(one,Math.max(two,three));
		int mid=0;
		if(one!=max&&one!=0)
			mid=one;
		if(two!=max&&two!=0)
			mid=two;
		if(three!=max&&three!=0)
			mid=three;
		System.out.println(ans+Math.min(mid,max/2));
	}
}

import java.awt.List;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map.Entry;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.Vector;

public class Main {

	public static void main(String[] args) throws IOException{
		  	FastScanner sc = new FastScanner();
			PrintWriter out = new PrintWriter(System.out);
			int r =sc.nextInt();
			int g =sc.nextInt();
			int b =sc.nextInt();
			int ans =0;
			int min =Math.min(r, g);
			min=Math.min(min, b);
			r-=min; g-=min; b-=min;
			ans+=(r+g+b)/3 ;
			System.out.println(min+ans);

	}

	static void generate(int[] p, int L, int R) {
		  if (L == R) {

		  }else { // numbers at positions [0, L-1] are set, try to set L-th position
		    for (int i = L; i <= R; i++) {
		    	int tmp = p[L]; p[L] = p[i]; p[i] = tmp;
		      generate(p, L+1, R);
		      tmp = p[L]; p[L] = p[i]; p[i] = tmp;

		    }
		  }
		}

}

class FastScanner {

    BufferedReader br;
    StringTokenizer st;

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

    public FastScanner(String s) {
        try {
            br = new BufferedReader(new FileReader(s));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    String nextToken() {
        while (st == null || !st.hasMoreElements()) {
            try {

                st = new StringTokenizer(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return st.nextToken();
    }

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

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

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

}

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long[] rgb = new long[3];
        long min = Long.MAX_VALUE;
        for (int i = 0; i <3; i ++) {
            rgb[i] = in.nextLong();
        }
        int zero_count = 0;
        long answer = 0;
        long sum = 0;
        while (zero_count < 2) {
            for (int i = 0; i < 3; i++) if (rgb[i] < min && rgb[i] != 0) min = rgb[i];
            for (int i = 0; i < 3; i++) {
                rgb[i] -= min;
                if (rgb[i] == 0) zero_count++;
                sum += rgb[i];
            }
            answer += min;
            if (sum < 3 || zero_count == 2) {
                System.out.println(answer);
                System.exit(0);
            }
        }
    }
}

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

public class ladder {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in = new Scanner(System.in);
		int[] colors = { in.nextInt(), in.nextInt(), in.nextInt() };
		Arrays.sort(colors);
		int count = 0;
		while (colors[1] > 0) {
//			System.out.println(Arrays.toString(colors));
			if(colors[2]-colors[0]<2){
				count+=colors[0];
				colors[2]-=colors[0];
				colors[1]-=colors[0];
				colors[0]=0;
			}
			int diff = colors[2] - colors[1];

			if (diff > 1) {
				diff = Math.min(diff, colors[1] * 2);
				count += diff / 2;
				diff /= 2;
				colors[2] -= diff * 2;
				if (diff < colors[1] - colors[0]) {
					colors[1] -= diff;
				} else {
					diff -= colors[1] - colors[0];
					colors[1] = colors[0];
					colors[0] -= diff / 2;
					colors[1] -= diff - diff / 2;
				}
			} else {
				if (colors[0] == colors[1]) {
					count += colors[0];
					colors[2] -= colors[0];
					colors[1] -= colors[0];
					colors[0] -= colors[0];
				} else {
					if (colors[2] > 1) {
						colors[1]--;
						colors[2] -= 2;
						count++;
					} else {
						break;
					}
				}
			}
			Arrays.sort(colors);
			if (false)
				break;
		}
		System.out.println(count);
	}

}

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

public class Main {
	public static long[] a, b;

	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		a = new long[3];
		b = new long[3];
		for (int i = 0; i < 3; i++) {
			a[i] = s.nextInt();
			b[i] = a[i];
		}
		Arrays.sort(a);
		Arrays.sort(b);
		if (a[1] - a[0] >= a[2] - a[1]) {
			System.out.println(solve1());
		} else {
			System.out.println(solve2());
		}
	}

	public static long solve1() {
		long res = a[0];
		for (int i = 0; i < 3; i++) {
			a[i] -= res;
		}
		long d = a[2] - a[1];
		if (d >= a[1]) {
			res += a[1];
		} else {
			res += d;
			a[1] -= d;
			a[2] -= 2 * d;
			res += (a[1] / 3) * 2;
			a[1] %= 3;
			if (a[1] == 2) {
				res++;
			}
		}
		return res;
	}

	public static long solve2() {
		long res = 0;
		long d = b[1] - b[0];
		res += d;
		b[1] -= d;
		b[2] -= 2 * d;
		if ((b[0] + b[1]) * 2 <= b[2]) {
			res += (b[0] + b[1]) * 2;
		} else {
			d = b[2] - b[1];
			long x = d / 3;
			res += x * 2;
			b[0] -= x;
			b[1] -= x;
			b[2] -= 4 * x;
			res += b[0];
		}
		return res;
	}

}

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

public class TableDecorations_
{
	public static void main(String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int[] arr = new int[3];
		arr[0] = sc.nextInt();
		arr[1] = sc.nextInt();
		arr[2] = sc.nextInt();

		Arrays.sort(arr);

		if(arr[0] + arr[1] <= arr[2])
			System.out.println(arr[0] + arr[1]);
		else
			System.out.println(((long)arr[0] + arr[1] + arr[2])/3);

	}
}

import java.util.Scanner;

public class cf478c {
	static final Scanner sc = new Scanner(System.in);
	static int maxTables(int red, int green, int blue) {
		long sum = (long)red + green + blue;
		int maxByCol = Math.max(red, Math.max(green, blue)); // Max. balloons belonging to one colour

		if ((long)(3 * maxByCol) > 2 * sum)
			return (int)(sum - maxByCol);
		else
			return (int)(sum / 3);
	}
	public static void main(String[] args) {
		int red = sc.nextInt();
		int blue = sc.nextInt();
		int green = sc.nextInt();

		int decoratedTables = maxTables(red, green, blue);
		System.out.print(decoratedTables);
	}
}

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

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

public class cf478c {

    public static void main(String[] args) throws IOException {
        int r = rni(), g = ni(), b = ni();
        if (r + g + b - maxof(r, g, b) < maxof(r, g, b) / 2) {
            prln(r + g + b - maxof(r, g, b));
        } else {
            prln((r + g + b) / 3);
        }
        close();
    }

    static BufferedReader __in = new BufferedReader(new InputStreamReader(System.in));
    static PrintWriter __out = new PrintWriter(new OutputStreamWriter(System.out));
    static StringTokenizer input;
    static Random __rand = new Random();

    // references
    // IBIG = 1e9 + 7
    // IMAX ~= 2e10
    // LMAX ~= 9e18

    // constants
    static final int IBIG = 1000000007;
    static final int IMAX = 2147483647;
    static final int IMIN = -2147483648;
    static final long LMAX = 9223372036854775807L;
    static final long LMIN = -9223372036854775808L;
    // math util
    static int minof(int a, int b, int c) {return min(a, min(b, c));}
    static int minof(int... x) {if(x.length == 1) return x[0]; if(x.length == 2) return min(x[0], x[1]); if(x.length == 3) return min(x[0], min(x[1], x[2])); int min = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] < min) min = x[i]; return min;}
    static long minof(long a, long b, long c) {return min(a, min(b, c));}
    static long minof(long... x) {if(x.length == 1) return x[0]; if(x.length == 2) return min(x[0], x[1]); if(x.length == 3) return min(x[0], min(x[1], x[2])); long min = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] < min) min = x[i]; return min;}
    static int maxof(int a, int b, int c) {return max(a, max(b, c));}
    static int maxof(int... x) {if(x.length == 1) return x[0]; if(x.length == 2) return max(x[0], x[1]); if(x.length == 3) return max(x[0], max(x[1], x[2])); int max = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] > max) max = x[i]; return max;}
    static long maxof(long a, long b, long c) {return max(a, max(b, c));}
    static long maxof(long... x) {if(x.length == 1) return x[0]; if(x.length == 2) return max(x[0], x[1]); if(x.length == 3) return max(x[0], max(x[1], x[2])); long max = x[0]; for(int i = 1; i < x.length; ++i) if(x[i] > max) max = x[i]; return max;}
    static int powi(int a, int b) {if(a == 0) return 0; int ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static long powl(long a, int b) {if(a == 0) return 0; long ans = 1; while(b > 0) {if((b & 1) > 0) ans *= a; a *= a; b >>= 1;} return ans;}
    static int fli(double d) {return (int)d;}
    static int cei(double d) {return (int)ceil(d);}
    static long fll(double d) {return (long)d;}
    static long cel(double d) {return (long)ceil(d);}
    static int gcf(int a, int b) {return b == 0 ? a : gcf(b, a % b);}
    static long gcf(long a, long b) {return b == 0 ? a : gcf(b, a % b);}
    static int randInt(int min, int max) {return __rand.nextInt(max - min + 1) + min;}
    static long hash(long x) {x += 0x9e3779b97f4a7c15L; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9L; x = (x ^ (x >> 27)) * 0x94d049bb133111ebL; return x ^ (x >> 31);}
    // array util
    static void reverse(int[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {int swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(long[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {long swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void reverse(char[] a) {for(int i = 0, n = a.length, half = n / 2; i < half; ++i) {char swap = a[i]; a[i] = a[n - i - 1]; a[n - i - 1] = swap;}}
    static void shuffle(int[] a) {int n = a.length - 1; for(int i = 0; i < n; ++i) {int ind = randInt(i, n); int swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void shuffle(long[] a) {int n = a.length - 1; for(int i = 0; i < n; ++i) {int ind = randInt(i, n); long swap = a[i]; a[i] = a[ind]; a[ind] = swap;}}
    static void rsort(int[] a) {shuffle(a); sort(a);}
    static void rsort(long[] a) {shuffle(a); sort(a);}
    static int[] copy(int[] a) {int[] ans = new int[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static long[] copy(long[] a) {long[] ans = new long[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static char[] copy(char[] a) {char[] ans = new char[a.length]; for(int i = 0; i < a.length; ++i) ans[i] = a[i]; return ans;}
    static int[] sorted(int[] a) {int[] ans = copy(a); sort(ans); return ans;}
    static long[] sorted(long[] a) {long[] ans = copy(a); sort(ans); return ans;}
    static int[] rsorted(int[] a) {int[] ans = copy(a); rsort(ans); return ans;}
    static long[] rsorted(long[] a) {long[] ans = copy(a); rsort(ans); return ans;}
    // graph util
    static List<List<Integer>> graph(int n) {List<List<Integer>> g = new ArrayList<>(); for(int i = 0; i < n; ++i) g.add(new ArrayList<>()); return g;}
    static List<List<Integer>> graph(List<List<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) connect(g, rni() - 1, ni() - 1); return g;}
    static List<List<Integer>> graph(int n, int m) throws IOException {return graph(graph(n), m);}
    static List<List<Integer>> dgraph(List<List<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) connecto(g, rni() - 1, ni() - 1); return g;}
    static List<List<Integer>> dgraph(List<List<Integer>> g, int n, int m) throws IOException {return dgraph(graph(n), m);}
    static List<Set<Integer>> sgraph(int n) {List<Set<Integer>> g = new ArrayList<>(); for(int i = 0; i < n; ++i) g.add(new HashSet<>()); return g;}
    static List<Set<Integer>> sgraph(List<Set<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) connect(g, rni() - 1, ni() - 1); return g;}
    static List<Set<Integer>> sgraph(int n, int m) throws IOException {return sgraph(sgraph(n), m);}
    static List<Set<Integer>> dsgraph(List<Set<Integer>> g, int m) throws IOException {for(int i = 0; i < m; ++i) connecto(g, rni() - 1, ni() - 1); return g;}
    static List<Set<Integer>> dsgraph(List<Set<Integer>> g, int n, int m) throws IOException {return dsgraph(sgraph(n), m);}
    static void connect(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).add(v); g.get(v).add(u);}
    static void connecto(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).add(v);}
    static void dconnect(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).remove(v); g.get(v).remove(u);}
    static void dconnecto(List<? extends Collection<Integer>> g, int u, int v) {g.get(u).remove(v);}
    // input
    static void r() throws IOException {input = new StringTokenizer(__in.readLine());}
    static int ri() throws IOException {return Integer.parseInt(__in.readLine());}
    static long rl() throws IOException {return Long.parseLong(__in.readLine());}
    static int[] ria(int n) throws IOException {int[] a = new int[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Integer.parseInt(input.nextToken()); return a;}
    static int[] riam1(int n) throws IOException {int[] a = new int[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Integer.parseInt(input.nextToken()) - 1; return a;}
    static long[] rla(int n) throws IOException {long[] a = new long[n]; input = new StringTokenizer(__in.readLine()); for(int i = 0; i < n; ++i) a[i] = Long.parseLong(input.nextToken()); return a;}
    static char[] rcha() throws IOException {return __in.readLine().toCharArray();}
    static String rline() throws IOException {return __in.readLine();}
    static int rni() throws IOException {input = new StringTokenizer(__in.readLine()); return Integer.parseInt(input.nextToken());}
    static int ni() {return Integer.parseInt(input.nextToken());}
    static long rnl() throws IOException {input = new StringTokenizer(__in.readLine()); return Long.parseLong(input.nextToken());}
    static long nl() {return Long.parseLong(input.nextToken());}
    // output
    static void pr(int i) {__out.print(i);}
    static void prln(int i) {__out.println(i);}
    static void pr(long l) {__out.print(l);}
    static void prln(long l) {__out.println(l);}
    static void pr(double d) {__out.print(d);}
    static void prln(double d) {__out.println(d);}
    static void pr(char c) {__out.print(c);}
    static void prln(char c) {__out.println(c);}
    static void pr(char[] s) {__out.print(new String(s));}
    static void prln(char[] s) {__out.println(new String(s));}
    static void pr(String s) {__out.print(s);}
    static void prln(String s) {__out.println(s);}
    static void pr(Object o) {__out.print(o);}
    static void prln(Object o) {__out.println(o);}
    static void prln() {__out.println();}
    static void pryes() {__out.println("yes");}
    static void pry() {__out.println("Yes");}
    static void prY() {__out.println("YES");}
    static void prno() {__out.println("no");}
    static void prn() {__out.println("No");}
    static void prN() {__out.println("NO");}
    static void pryesno(boolean b) {__out.println(b ? "yes" : "no");};
    static void pryn(boolean b) {__out.println(b ? "Yes" : "No");}
    static void prYN(boolean b) {__out.println(b ? "YES" : "NO");}
    static void prln(int... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static void prln(long... a) {for(int i = 0, len = a.length - 1; i < len; __out.print(a[i]), __out.print(' '), ++i); __out.println(a[a.length - 1]);}
    static <T> void prln(Collection<T> c) {int n = c.size() - 1; Iterator<T> iter = c.iterator(); for(int i = 0; i < n; __out.print(iter.next()), __out.print(' '), ++i); if(n >= 0) __out.println(iter.next()); else __out.println();}
    static void h() {__out.println("hlfd");}
    static void flush() {__out.flush();}
    static void close() {__out.close();}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastReader in = new FastReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, FastReader s, PrintWriter out) {
            long r = s.nextLong();
            long g = s.nextLong();
            long b = s.nextLong();

            long ans = 0L;
            long min = Math.min(r, Math.min(g, b));
            ans += min;
            r -= min;
            g -= min;
            b -= min;

            if (b == 0L) {
                ans += Math.min((Math.max(r, g) / 2L), Math.min(r, g));
            } else if (g == 0L) {
                ans += Math.min((Math.max(r, b) / 2L), Math.min(r, b));
            } else if (r == 0L) {
                ans += Math.min((Math.max(g, b) / 2L), Math.min(g, b));
            }

            out.println(ans);

        }

    }

    static class FastReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private FastReader.SpaceCharFilter filter;

        public FastReader(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++];
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}

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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main (String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader (inputStream);
		PrintWriter out = new PrintWriter (outputStream);
		TaskC solver = new TaskC ();
		solver.solve (1, in, out);
		out.close ();
	}

	static class TaskC {
		public void solve (int testNumber, InputReader in, PrintWriter out) {
//if we make all types ballons equal, then all the rest are rgb
//else make using largest two
			long[] arr = new long[5];
			for (int i = 0; i<3; i++) {
				arr[i] = in.nextLong ();
			}
			Arrays.sort (arr, 0, 3);
			long res = (long) Math.min (arr[2]-arr[1], arr[1]-arr[0]);
//first take the highest one twice and second one once
			arr[1] -= res;
			arr[2] -= res*2;
//compare arr[1] and arr[0], and check how much times can you use arr[1] and arr[0] only
			long os = (arr[1]-arr[0])/3;
			res += os*2;
			arr[1] -= os*3;
			arr[2] -= os*3;
//now it's kind of 3 3 2 or 2 2 2 or 4 4 2
			res += arr[0];
			out.println (res);
		/*if (arr[1] == arr[2]) {
			res += (arr[1]-arr[0])/3;
			arr[2] -= ((arr[1]-arr[0])/3)*3;
			if (arr[2] == arr[0]) {
				res += arr[0];
				out.println (res);
				return;
			}
			arr[1] = arr[2];
			if (arr[2]>=3) {
				arr[2] -= 3;
				res += 2;
//				out.println (res);
				arr[1] = arr[2];
			}
			else if (arr[1] == 2 || arr[1] == 1) {
				res++;
				out.println (res);
				return;
			}
		}
		Arrays.sort (arr, 0, 3);
//4 2 2 result 2, 3 2 2 result 2, 5 2 2 result 3,
		if (arr[2]>arr[0]*2) {
			res += arr[0];
			arr[2] -= arr[0]*2;
			Arrays.sort (arr, 0, 3);
			res += Math.min (arr[2]/2, arr[1]);
		}
		else {
			res += arr[0];
		}
		out.println (res);*/
		}

	}

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

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

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

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

	}
}

import java.util.*;
public class TableDecorations {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int[] arr = new int[]{in.nextInt(), in.nextInt(), in.nextInt()};
        Arrays.sort(arr);
        int res = 0;
        arr[2] -= arr[0];
        arr[1] -= arr[0];
        res += arr[0];
        arr[0] = 0;
        int n = Math.min(arr[2] - arr[1], Math.min(arr[1], arr[2] / 2));
        arr[1] -= n;
        arr[2] -= n * 2;
        res += n;
        n = arr[1] / 3;
        arr[1] -= n * 3;
        arr[2] -= n * 3;
        res += n;
        if (arr[1] == 2) {
            res++;
        }
        System.out.println(res);
    }
}

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Arrays;
import java.util.Collections;

public class Problema1 {

	public static void main(String[] args) {

        Scanner reader = new Scanner(System.in);
        int red = reader.nextInt();
        int green = reader.nextInt();
        int blue = reader.nextInt();

        Integer[] array = {red,green,blue} ;
        int output = 0;

        Arrays.sort (array, Collections.reverseOrder()) ;

        if(array[0] == array[1] && array[0] + array[1] > 2) {
        	output = output + array[0] / 2;

        	array[0] -= array[0];
        	array[1] -= array[0] / 2;
        }
        else {
        	int dobles = array[0] / 2;
            if(Math.abs(dobles - array[1]) >= 0) {
            	int max = Math.min(dobles, array[1]);
            	output += max;

            	array[0] -= max * 2;
            	array[1] -= max;
            }
        }

        while(array[0] + array[1] > 2 && array[0] != 0 && array[1] != 0) {
        	output++;

        	if(array[0] > array[1]) {
        		array[0] -= 2;
        		array[1]--;
        	}
        	else {
        		array[1] -= 2;
        		array[0]--;
        	}
        }

        while(array[0] + array[1] + array[2] > 2) {
        	if(array[2] != 0) {
        		array[0]--;
        		array[1]--;
        		array[2]--;

        		output ++;
        	}
        	else {
        		break;
        	};
        }

        System.out.println(output);

        reader.close();

	}

}

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

public class Main {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();

        int[] arr = { sc.nextInt(), sc.nextInt(), sc .nextInt() };
        Arrays.sort(arr);

        int min = arr[0];
        for (int i = 0; i < arr.length; i++)
            arr[i] -= min;

        int diff = arr[2] - arr[1];
        arr[1] -= diff;
        arr[2] -= 2 * diff;

        int triples = Math.min(arr[1], arr[2]) / 3;
        arr[1] -= triples * 3;
        arr[2] -= triples * 3;

        int extra = 0;
        if ((arr[1] >= 1 && arr[2] >= 2) || (arr[2] >= 1 && arr[1] >= 2))
            extra = 1;

        int total = min + diff + 2 * triples + extra;
        System.out.println(total);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class T478C {
	public void solve(long r, long g, long b) {
		long[] a = {r, g, b};
		System.out.println(a[2] > 2 * (a[0] + a[1]) ? a[0] + a[1] : (a[0] + a[1] + a[2]) / 3);
	}

	public static void main(String[] args) {
		FastScanner in = new FastScanner();
		new T478C().solve(in.nextLong(), in.nextLong(), in.nextLong());
	}
	static class FastScanner {

		BufferedReader br;
		StringTokenizer st;

		public FastScanner(String s) {
			try {
				br = new BufferedReader(new FileReader(s));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

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

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

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

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

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

	}
}

import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.*;
import java.util.List;

public class Question {

    public static void main(String[] args) {
        new Question(System.in, System.out);

/*        for (int i = 0; i < 10; i++)
            System.out.println("i : " + i + ", (ch) I : " + ((char) i));*/
    }
    static class Solver {
        long r,g,b;
        InputReader in;
        PrintWriter out;
        int func3(int r , int g)
        {
            if(r<g)
            {
                int t =r;
                r=g;
                g=r;
            }

                if(r%2==0)
                    return r/2;
                else{
                    if(g-r/2>=2)
                        return r/2+1;
                    else {
                        return r / 2;
                    }
                }
        }
        int func2(int r, int g,int b)
        {

            if(r==0&&g==0 || g==0&&b==0 || r==0&&b==0)
                return 0;
            else if(r==0 || g==0 || b==0)
            {
                if(r==0)
                    return func3(g,b);
                else if(g==0)
                    return func3(r,b);
                else  if(b==0)
                    return func3(r,g);
            }
            if(r==g && g==b)
                return r;
            int minimum = min(r,g,b);
            int maximum = max(r,g,b);
            int middle=0;
            int[] temp = new int[3];
            temp[0]=r;
            temp[1]=g;
            temp[2]=b;
            if(minimum == maximum) {
                if(maximum==0)maximum=1;else if(maximum==1)maximum=2;else maximum=0;
            }
            if (minimum == 0 && maximum == 1 || minimum == 1 && maximum == 0) {
                middle = 2;
            } else if (minimum == 1 && maximum == 2 || minimum == 2 && maximum == 1) {
                middle = 0;
            } else if (minimum == 0 && maximum == 2 || minimum == 2 && maximum == 0) {
                middle = 1;
            }
            int diff = (temp[maximum]-temp[middle])/2;
          if((temp[maximum]-temp[middle])%2==0 && diff!=0){
            temp[maximum] -= 2 * diff;
            temp[minimum] -= diff;
            return diff + func2(temp[0], temp[1], temp[2]);
        }
            else{
              temp[maximum] -=  2*(diff+1);
            temp[minimum] -=  diff+1;
            return diff +1+ func2(temp[0],temp[1],temp[2]);
          }

        }
        int min(int r,int g,int b)
        {
            if(r<g && r<b)
                return 0;
            else if(g<b)
                return 1;
            else
                return 2;
        }
        int max(int r,int g,int b)
        {
            if(r>g && r>b)
                return 0;
            else if(g>b)
                return 1;
            else
                return 2;
        }
/*        int func1(int r,int g)
        {
            if(r==0||g==0)
                return 0;
            if(r<g)
            {
                if(g>=2)
                g-=2;
            else return 0;
                r--;
            }
            else {
                if(r>=2)
                    r-=2;
                else return 0;
                g--;

            }
            return 1+ func1(r,g);
        }
        int func(int r , int g ,int b)
        {
            if(r==0&&g==0 || g==0&&b==0 || r==0&&b==0)
                return 0;
            else if(r==0 || g==0 || b==0)
            {
                if(r==0)
                return func1(g,b);
                else if(g==0)
                        return func1(r,b);
                else  if(b==0)
                    return func1(r,g);
            }
            if(r==g && g==b)
                return r;
            int[] temp = new int[3];
            temp[0]=r;
            temp[1]=g;
            temp[2]=b;

         int min = min(r,g,b);
            int max = max(r,g,b);
           // System.out.println("min: " + min + " max: " +max);
            if(min!=max)
            {
                temp[min]--;
                if(temp[max]>=2)
                temp[max]-=2;
                else
                return 0;

            }
            else {
                if(max==0)max=1;else if(max==1)max=2;else max=0;
                temp[min]--;
                if(temp[max]>=2)
                temp[max]-=2;
                else
                    return 0;

            }

            return 1+ func(temp[0],temp[1],temp[2]);
        }*/
        void solve() throws IOException
        {
            int r,g,b;
          r = in.nextInt();
          g =  in.nextInt();
          b = in.nextInt();
            int ans=0;
           if(r==g && g==b)
           {
               ans= r;
           }
           else {
            ans = func2(r,g,b);
           }
            out.println(ans);
        }

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

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

        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++];
        }

        public int nextInt() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();

                res *= 10;
                res += c & 15;

                c = read();
            } while (!isSpaceChar(c));

            return res * sgn;
        }

        public int[] nextIntArray(int arraySize) {
            int array[] = new int[arraySize];

            for (int i = 0; i < arraySize; i++)
                array[i] = nextInt();

            return array;
        }

        public long nextLong() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            int sign = 1;

            if (c == '-') {
                sign = -1;

                c = read();
            }

            long result = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();

                result *= 10;
                result += c & 15;

                c = read();
            } while (!isSpaceChar(c));

            return result * sign;
        }

        public long[] nextLongArray(int arraySize) {
            long array[] = new long[arraySize];

            for (int i = 0; i < arraySize; i++)
                array[i] = nextLong();

            return array;
        }

        public float nextFloat() {
            float result, div;
            byte c;

            result = 0;
            div = 1;
            c = (byte) read();

            while (c <= ' ')
                c = (byte) read();

            boolean isNegative = (c == '-');

            if (isNegative)
                c = (byte) read();

            do {
                result = result * 10 + c - '0';
            } while ((c = (byte) read()) >= '0' && c <= '9');

            if (c == '.')
                while ((c = (byte) read()) >= '0' && c <= '9')
                    result += (c - '0') / (div *= 10);

            if (isNegative)
                return -result;

            return result;
        }

        public double nextDouble() {
            double ret = 0, div = 1;
            byte c = (byte) read();

            while (c <= ' ')
                c = (byte) read();

            boolean neg = (c == '-');

            if (neg)
                c = (byte) read();

            do {
                ret = ret * 10 + c - '0';
            } while ((c = (byte) read()) >= '0' && c <= '9');

            if (c == '.')
                while ((c = (byte) read()) >= '0' && c <= '9')
                    ret += (c - '0') / (div *= 10);

            if (neg)
                return -ret;

            return ret;
        }

        public String next() {
            int c = read();

            while (isSpaceChar(c))
                c = read();

            StringBuilder res = new StringBuilder();

            do {
                res.appendCodePoint(c);

                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String nextLine() {
            int c = read();

            StringBuilder result = new StringBuilder();

            do {
                result.appendCodePoint(c);

                c = read();
            } while (!isNewLine(c));

            return result.toString();
        }

        public boolean isNewLine(int c) {
            return c == '\n';
        }

        public void close() {
            try {
                stream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

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

    }

    Question(InputStream inputStream, OutputStream outputStream) {
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        Solver solver = new Solver(in, out);

        try {
            solver.solve();
        } catch (IOException e) {
            e.printStackTrace();
        }
        in.close();
        out.flush();
        out.close();
    }

}

//package javaapplication1;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {

    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw=new PrintWriter(new PrintStream(System.out));
        String [] input=br.readLine().split(" ");
        long r=Long.parseLong(input[0]);
        long g=Long.parseLong(input[1]);
        long b=Long.parseLong(input[2]);
        List<Long>nums=new ArrayList<>();
        if(r!=0)
           nums.add(r);
        if(b!=0)
        nums.add(b);
        if(g!=0)
        nums.add(g);
        List<Long>numbers=new ArrayList<>();
        numbers.addAll(nums);
        long max,min,ans=0,elsum=0,minans=0;
        Collections.sort(nums);
        if(nums.size()>2)
        {minans=nums.get(0);}
        nums.clear();
        while(numbers.size()>1)
        {
          elsum=0;
          nums.addAll(numbers);
          //simple algorithm is needed
          //first get the max /2 and add the rem and add min to it
          Collections.sort(nums);
          min=nums.get(0);
          max=nums.get(nums.size()-1);
           if(max==min&&nums.size()==3){
             ans+=max;break;
            }
           //if we have the max /2 as pairs >= min then we take it
           if(max/2>=min)
           {
               ans+=min;
               nums.set(0, (long)0);
               nums.set(nums.size()-1,max-(min*2));
           }
           else{
               ans+=max/2;
               nums.set(0,min-(max/2));
               nums.set(nums.size()-1,(max%2));
           }
           //System.out.println(nums);
           //filter
           numbers.clear();
            for (int i = 0; i < nums.size(); i++) {
                if(nums.get(i)!=0)
                { numbers.add(nums.get(i));elsum+=nums.get(i);}
            }
           nums.clear();
           if(elsum<3)
               break;
        }
            System.out.println(Math.max(ans,minans));
    }

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Round_273_Div_2C {

	private static BufferedReader in;
	private static StringTokenizer st;
	private static PrintWriter out;

	public static void main(String[] args) throws Exception {
		standart();
//		file("defense");
		int a[] = new int [3];
		for (int i = 0; i < 3; i++) {
			a[i] = nextInt();
		}
		Arrays.sort(a);
		if(2 * (a[0] + a[1]) <= a[2]){
			a[2] = 2 * (a[0] + a[1]);
		}
		System.out.println((a[0]+a[1]+a[2])/3);
		out.close();
	}

	private static double nextDouble() throws Exception {
		return Double.parseDouble(next());
	}

	private static long nextLong() throws Exception {
		return Long.parseLong(next());
	}

	private static int nextInt() throws Exception {
		return Integer.parseInt(next());
	}

	private static String next() throws IOException {
		while(!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

	private static void file(String file) throws IOException {
		in = new BufferedReader(new FileReader(file+".in"));
		st = new StringTokenizer("");
		out = new PrintWriter(new BufferedWriter(new FileWriter(file+".out")));
	}

	private static void standart() {
		in = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer("");
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
	}
}

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

public class TableDeorations {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scn=new Scanner(System.in);
		long []a=new long[3];
		a[0]=scn.nextLong();
		a[1]=scn.nextLong();
		a[2]=scn.nextLong();
		Arrays.sort(a);
//		for(int i=0;i<3;i++) {
//			System.out.println(a[i]);
//		}
		long sum=a[0];
		a[1]-=sum;
		a[2]-=sum;
		long x=a[1]+a[2];
		//System.out.println(x+" x"+(long)a[1]+" "+(long)a[2]+" "+(long)a[0]);
		if(x>=3) {
			if(a[2]>=a[1]*2l)
			sum+=a[1];
			else {
				long y=a[1]*2l/3l;
				//System.out.println(y);
				sum+=y;
				a[2]-=a[1];
				long z=(a[1]*2l)%3l;
				sum+=Math.min(z, a[2]);
			}
			System.out.println(sum);
		}else{
			System.out.println(sum);
		}
	}

}

import java.util.*;
import java.io.*;
public class Prac {

	public static void main(String[] args){
		FastReader sc=new FastReader();
		PrintStream ps=System.out;

		int r=sc.nextInt(), g=sc.nextInt(), b=sc.nextInt();

		int[] ar={r, g, b};
		int ans=0;

		int min=Math.min(r, Math.min(g, b));
		ans=min;

		ar[0]-=min;ar[1]-=min;ar[2]-=min;
		Arrays.sort(ar);
		if(2*ar[1]-ar[2]>=0){
			int d=ar[2]-ar[1];
			ar[2]-=2*d;
			ans+=d;
			ar[1]=ar[2];
			ans+=(2*ar[1])/3;
		}
		ps.println(ans);
	}
}

class FastReader  {
    BufferedReader br;
    StringTokenizer st;

    public FastReader()
    {
        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;
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class C_Round_273_Div2 {

	public static long MOD = 1000000007;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		long[] data = new long[3];
		for (int i = 0; i < 3; i++) {
			data[i] = in.nextInt();
		}
		long result = (data[0] + data[1] + data[2])/3;
		out.println(result);
		out.close();
	}

	static long max(long mid, long[] data) {
		long x = data[0] - mid;
		long y = data[1] - mid;
		long z = data[2] - mid;
		long result = mid;
		long[] tmp = { x, y, z };
		while (true) {
			Arrays.sort(tmp);
			long v = 0;
			if (tmp[0] != 0) {
				v = (tmp[2] / 2 > tmp[0] ? tmp[0] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[0] -= v;
			} else {
				v = (tmp[2] / 2 > tmp[1] ? tmp[1] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[1] -= v;
			}
			result += v;
			if (v == 0) {
				break;
			}
		}
		return result;

	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

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

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

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

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

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

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

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

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

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}

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

public class SolutionC {
	public static void main(String[] args){
		new SolutionC().run();
	}
	int a[];
	void solve(){
		a = new int[3];
		for(int i = 0; i < 3; i++) a[i] = in.nextInt();
		if( a[2] > 2 *(a[0] + a[1])){
			out.println(a[0] + a[1]);
			return;
		}
		out.println((a[0] + a[1] + a[2])/3);
	}
	FastScanner in;
	PrintWriter out;
	void run(){
		in = new FastScanner(System.in);
		out = new PrintWriter(new OutputStreamWriter(System.out));
		solve();
		out.close();
	}
	void runIO(){
		try{
			in = new FastScanner(new File("a.in"));
			out = new PrintWriter(new FileWriter(new File("a.out")));
			solve();
			out.close();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	class FastScanner{
		BufferedReader bf;
		StringTokenizer st;
		public FastScanner(File f){
			try{
				bf = new BufferedReader(new FileReader(f));
			}
			catch(IOException ex){
				ex.printStackTrace();
			}
		}
		public FastScanner(InputStream is){
			bf = new BufferedReader(new InputStreamReader(is));
		}
		String next(){
			while(st == null || !st.hasMoreTokens()){
				try{
					st = new StringTokenizer(bf.readLine());
				}
				catch(IOException ex){
					ex.printStackTrace();
				}
			}
			return st.nextToken();
		}
		int nextInt(){
			return Integer.parseInt(next());
		}
		double nextDouble(){
			return Double.parseDouble(next());
		}
		float nextFloat(){
			return Float.parseFloat(next());
		}
		String nextLine(){
			try{
				return bf.readLine();
			}
			catch(Exception ex){
				ex.printStackTrace();
			}
			return "";
		}
	}
}

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

public class Main {
    public static void main(String[] args) throws IOException {
        Scan s = new Scan();
        int r = s.scanInt();
        int g = s.scanInt();
        int b = s.scanInt();
        System.out.println(solve(r,g,b));
    }

    private static int solve(int r,int g,int b){
        if(r + g + b < 3 || g == 0 && b == 0 || b == 0 && r == 0 || r == 0 && g == 0) return 0;
       int[] arr = {r,g,b};
       Arrays.sort(arr);
       return arr[0] - arr[1] + arr[2];
    }
}

class Scan
{
    private byte[] buf=new byte[1024];    //Buffer of Bytes
    private int index;
    private InputStream in;
    private int total;
    public Scan()
    {
        in=System.in;
    }
    public int scan()throws IOException    //Scan method used to scan buf
    {
        if(total<0)
        throw new InputMismatchException();
        if(index>=total)
        {
            index=0;
            total=in.read(buf);
            if(total<=0)
            return -1;
        }
        return buf[index++];
    }
    public int scanInt()throws IOException
    {
        int integer=0;
        int n=scan();
        while(isWhiteSpace(n))    //Removing starting whitespaces
        n=scan();
        int neg=1;
        if(n=='-')                //If Negative Sign encounters
        {
            neg=-1;
            n=scan();
        }
        while(!isWhiteSpace(n))
        {
            if(n>='0'&&n<='9')
            {
                integer*=10;
                integer+=n-'0';
                n=scan();
            }
            else throw new InputMismatchException();
        }
        return neg*integer;
    }
    private boolean isWhiteSpace(int n)
    {
        if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
        return true;
        return false;
    }
}

import java.util.*;

public class C478{
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		long a[] = new long[3];
		a[0] = in.nextLong();
		a[1] = in.nextLong();
		a[2] = in.nextLong();

		Arrays.sort(a);
		a[1] = a[1]-a[0];
		a[2] = a[2]-a[0];

		long tmp=a[1]/3;
		a[0]+=2*tmp;
		a[1] = a[1]%3;
		a[2] -= tmp*3;

		if(a[1]>=1 && a[2]>1){
			a[0]+=1;
		}
		System.out.println(a[0]);

	}
}

/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x478C
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int R = Integer.parseInt(st.nextToken());
         int G = Integer.parseInt(st.nextToken());
         int B = Integer.parseInt(st.nextToken());
         long[] arr = new long[3];
         arr[0] = R;
         arr[1] = G;
         arr[2] = B;
         long res = 0L;
         for(int a=0; a < 3; a++)
            for(int b=0; b < 3; b++)
               for(int c=0; c < 3; c++)
                  if(a != b && a != c && b != c)
                  {
                     long cnt = arr[a]+arr[b];
                     res = Math.max(res, Math.min(cnt/2, arr[c]));
                  }
         System.out.println(res);
      }
   }

import java.util.*;
public class marte{

private int contor=0;

public static void main (String args[]) {

Scanner input=new Scanner(System.in);

HashMap<Integer, Integer> map1= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> map2= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> finish= new HashMap<Integer, Integer>();
HashMap<Integer, Integer> maxime= new HashMap<Integer, Integer>();

			Long r=input.nextLong();
			Long g=input.nextLong();
			Long b=input.nextLong();

			Long mese=0L;
			Long max=-1L;
			Long min=-1L;
			Long med=-1L;
			Long temp;

			if(r-g>=0L && r-b>=0L)

			{

			max=r;

			if(g-b>=0L) {med=g;min=b;}
			else {med=b;min=g;}

			}

			else if(g-r>=0L && g-b>=0L)

			{

			max=g;

			if(r-b>=0L) {med=r;min=b;}
			else {med=b;min=r;}

			}

			else if(b-r>=0L && b-g>=0L)

			{

			max=b;

			if(r-g>=0L) {med=r;min=g;}
			else {med=g;min=r;}

			}

			mese+=min;
			max-=min;
			med-=min;

			if(max-med>med) {mese+=med; 	  }

			else{
			    temp=max-med;
			    mese+=temp;
			    //	System.out.println(mese);

			    max-=2*temp;
			    med-=temp;

			    mese+=(max+med)/3;

			}

	System.out.println(mese);

	}

		}

import java.util.Scanner;
public class Main
{
  public static void main(String[]args)
  {
    Scanner sc=new Scanner(System.in);

    int i=sc.nextInt();
    int j=sc.nextInt();
    int k=sc.nextInt();

    int sum=i+j+k;
    System.out.println(sum/3);
  }
}

import java.io.*;
import java.util.*;
import java.nio.charset.StandardCharsets;
// import java.math.BigInteger;

public class C {
    static Writer wr;

    public static void main(String[] args) throws Exception {
        // long startTime = System.nanoTime();

        // String testString = "";
        // InputStream stream = new ByteArrayInputStream(testString.getBytes(StandardCharsets.UTF_8));
        // Reader in = new Reader(stream);

        Reader in = new Reader();
        BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

        wr = new Writer();

        /* Precomputation */

        // long elapsedTime = System.nanoTime() - startTime;
        // double seconds = (double)elapsedTime / 1000000000.0;
        // wr.writeRedLn(seconds);

        /* Input */
        long[] a = new long[3];

        for(int i=0;i<3;i++) {
            a[i] = in.nextLong();
        }

        Arrays.sort(a);

        long r = a[2];
        long g = a[1];
        long b = a[0];

        long ans = 0;

        if(r>=2*(g+b)) {
            ans = 2*(g+b);
        }
        else {
            // r is lt 2*(g+b)
            r-=b; g-=b; ans = b; b=0;

            if(r>= 2*g) {
                ans += g;
            }
            else {
                // r is lt 2*g
                ans += Math.min(r/2, g);
                if(r%2==1 && g>=2) ans++;
            }

        }

        out.write(ans + "\n");
        out.flush();
    }
}

class Writer {
    public void writeRedLn(Object x) { writeRedLn(x+""); }
    public void writeBlueLn(Object x) { writeBlueLn(x+""); }
    public void writeGreenLn(Object x) { writeGreenLn(x+""); }
    public void writePinkLn(Object x) { writePinkLn(x+""); }
    public void writeRedLn(String x) { System.out.println((char)27 + "[31m" + (char)27 + "[40m" + x + (char)27 + "[0m"); }
    public void writeBlueLn(String x) { System.out.println((char)27 + "[34m" + (char)27 + "[3m" + x + (char)27 + "[0m"); }
    public void writeGreenLn(String x) { System.out.println((char)27 + "[32m" + (char)27 + "[3m" + x + (char)27 + "[0m"); }
    public void writePinkLn(String x) { System.out.println((char)27 + "[30m" + (char)27 + "[45m" + x + (char)27 + "[0m"); }
    public void writeRed(String x) { System.out.print((char)27 + "[31m" + (char)27 + "[40m" + x + (char)27 + "[0m"); }
    public void writeBlue(String x) { System.out.print((char)27 + "[34m" + (char)27 + "[3m" + x + (char)27 + "[0m"); }
    public void writeGreen(String x) { System.out.print((char)27 + "[32m" + (char)27 + "[3m" + x + (char)27 + "[0m"); }
    public void writePink(String x) { System.out.print((char)27 + "[30m" + (char)27 + "[45m" + x + (char)27 + "[0m"); }
}

class Reader {
    final private int BUFFER_SIZE = 1 << 16;private DataInputStream din;private byte[] buffer;private int bufferPointer, bytesRead;
    public Reader(){din=new DataInputStream(System.in);buffer=new byte[BUFFER_SIZE];bufferPointer=bytesRead=0;}
    public Reader(InputStream stream){din=new DataInputStream(stream);buffer=new byte[BUFFER_SIZE];bufferPointer=bytesRead=0;}
    public String readLine()throws IOException{byte[] buf=new byte[1024];int cnt=0,c;
        while((c=read())!=-1){if(c=='\n')break;buf[cnt++]=(byte)c;}return new String(buf,0,cnt);}
    public char nextChar()throws IOException{byte c=read();while(c<=' ')c=read();return (char)c;}
    public int nextInt()throws IOException{int ret=0;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');
        if(neg)c=read();do{ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');if(neg)return -ret;return ret;}
    public long nextLong()throws IOException{long ret=0;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');
        if(neg)c=read();do{ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');if(neg)return -ret;return ret;}
    public double nextDouble()throws IOException{double ret=0,div=1;byte c=read();while(c<=' ')c=read();boolean neg=(c=='-');if(neg)c = read();do {ret=ret*10+c-'0';}while((c=read())>='0'&&c<='9');
        if(c=='.')while((c=read())>='0'&&c<='9')ret+=(c-'0')/(div*=10);if(neg)return -ret;return ret;}
    private void fillBuffer()throws IOException{bytesRead=din.read(buffer,bufferPointer=0,BUFFER_SIZE);if(bytesRead==-1)buffer[0]=-1;}
    private byte read()throws IOException{if(bufferPointer==bytesRead)fillBuffer();return buffer[bufferPointer++];}
    public void close()throws IOException{if(din==null) return;din.close();}
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class C_Round_273_Div2 {

	public static long MOD = 1000000007;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		long[] data = new long[3];
		for (int i = 0; i < 3; i++) {
			data[i] = in.nextInt();
		}
		Arrays.sort(data);

		long result = 0;
		if(data[0] != 0){
			result =   (data[0] + data[1] + data[2])/3;
		}else if(data[1] != 0){
			result =2* (Math.min(data[1],data[2]))/3;
		}
		out.println(result);
		out.close();
	}

	static long max(long mid, long[] data) {
		long x = data[0] - mid;
		long y = data[1] - mid;
		long z = data[2] - mid;
		long result = mid;
		long[] tmp = { x, y, z };
		while (true) {
			Arrays.sort(tmp);
			long v = 0;
			if (tmp[0] != 0) {
				v = (tmp[2] / 2 > tmp[0] ? tmp[0] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[0] -= v;
			} else {
				v = (tmp[2] / 2 > tmp[1] ? tmp[1] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[1] -= v;
			}
			result += v;
			if (v == 0) {
				break;
			}
		}
		return result;

	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

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

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

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

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

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

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

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

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

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}

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

public class Rextester{
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        br.close();
        int count=0;
        int[] array = new int[3];
        for(int i=0;i<3;i++){
            array[i]=new Integer(st.nextToken());
        }
        Arrays.sort(array);
        long a = array[0]+array[1];
        if(a*2<=array[2]){
            System.out.println(a);
        }
        else{
            long c = a+array[2];
            long left = c%3;
            long soln = (c-left)/3;
            System.out.println(soln);
        }
    }
}

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

public class tabledecorations {
    public static void main(String[] args){
        FastReader fastReader = new FastReader();
        int count=0;
        long[] val = new long[3];
        int t=3;
        int k;
        while(t-- >0){

            val[t] = fastReader.nextInt();
            if(val[t]>0){
                count++;
            }
        }
        Arrays.sort(val);
        if(((val[0]*3-val[0])+(val[1]*2-val[1])<=val[2])&&count>2){
            System.out.println(val[0]+val[1]);
        }
        else{
            if(count>2){
                System.out.println((val[0]+val[1]+val[2])/3);
            }
            else if(count==2){
                if((val[1]*3-val[1]<=val[2])){
                    System.out.println(val[1]);
                }
                else{
                    System.out.println(0);
                }
            }
            else{
                System.out.println(0);
            }
        }
    }
}
class FastReader {
    public static BufferedReader br;
    public static StringTokenizer st;
    public FastReader(){
        br = new BufferedReader(new InputStreamReader(System.in));
    }
    static String next() {
        while(st==null || !st.hasMoreElements()) try {
            st = new StringTokenizer(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return st.nextToken();
    }
    public static int nextInt(){
        return  Integer.parseInt(next());
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main4
{
    public static void main(String args[])throws Exception
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        st=new StringTokenizer(br.readLine());
        int a[]=new int[3];
        a[0]=Integer.parseInt(st.nextToken());
        a[1]=Integer.parseInt(st.nextToken());
        a[2]=Integer.parseInt(st.nextToken());
        Arrays.sort(a);
        long sum=(long)a[0]+(long)a[1]+(long)a[2];
        if(a[2]>(2* (a[0]+a[1])))
            System.out.print((a[0]+a[1]));
        else {
            sum/=3;
            System.out.print(sum);
        }
    }
}

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Arrays;
import java.util.StringTokenizer;

/*
 public class _478C{ }
 */

public class _478C
{
	public void solve() throws FileNotFoundException
	{
		InputStream inputStream = System.in;

		InputHelper inputHelper = new InputHelper(inputStream);

		PrintStream out = System.out;

		int[] b = new int[3];

		b[0] = inputHelper.readInteger();

		b[1] = inputHelper.readInteger();

		b[2] = inputHelper.readInteger();

		Arrays.sort(b);

		int ans = 0;

		while (true)
		{
			if ((b[2] - b[0] == 0) || (b[2] - b[1] == 1 && b[1] - b[0] == 0)
					|| (b[2] - b[1] == 0 && b[1] - b[0] == 1))
			{
				ans += b[0];
				break;
			}

			if (b[2] > b[1] && b[1] > b[0])
			{
				if (b[2] - b[1] == b[1] - b[0])
				{
					ans += (b[1] - b[0]);
					b[1] = b[0];
					b[2] = b[0];
				}
				else if (b[2] - b[1] > b[1] - b[0])
				{
					ans += (b[1] - b[0]);
					b[2] -= (2 * (b[1] - b[0]));
					b[1] = b[0];
				}
				else
				{
					int min = (b[2] - b[1]);
					ans += min;
					b[2] -= (2 * min);
					b[1] -= min;
				}
			}
			else if (b[2] > b[1] && b[1] == b[0])
			{
				int min = b[2] - b[1];

				ans += (min / 3);

				b[2] = b[1];
			}
			else if (b[2] == b[1] && b[1] > b[0])
			{
				int min = b[1] - b[0];

				if (min % 3 == 0 || min % 3 == 1)
				{
					ans += (2 * (min / 3));
				}
				else
				{
					ans += ((2 * (min / 3)) + 1);
				}
				b[2] = b[0];
				b[1] = b[0];
			}
		}

		out.print(ans);
		// actual solution

		// end here
	}

	public static void main(String[] args) throws FileNotFoundException
	{
		(new _478C()).solve();
	}

	class InputHelper
	{
		StringTokenizer tokenizer = null;
		private BufferedReader bufferedReader;

		public InputHelper(InputStream inputStream)
		{
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream);
			bufferedReader = new BufferedReader(inputStreamReader, 16384);
		}

		public String read()
		{
			while (tokenizer == null || !tokenizer.hasMoreTokens())
			{
				try
				{
					String line = bufferedReader.readLine();
					if (line == null)
					{
						return null;
					}
					tokenizer = new StringTokenizer(line);
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}

			return tokenizer.nextToken();
		}

		public Integer readInteger()
		{
			return Integer.parseInt(read());
		}

		public Long readLong()
		{
			return Long.parseLong(read());
		}
	}
}

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

public class C {

  public static void main(String[] args) throws IOException {
    Reader reader = new Reader();
    reader.initConsoleReading();
    int a, b, c;
    a = reader.nextInt();
    b = reader.nextInt();
    c = reader.nextInt();
    long max = 0;
    max = Math.max(max, solve(a, b, c));
    max = Math.max(max, solve(a, c, b));
    max = Math.max(max, solve(b, c, a));
    System.out.println(max);
    reader.dispose();
  }

  private static int solve(int a, int b, int c) {
    int x = Math.min(build(a, b), c);
    int y = Math.min(c >> 1, a + b);
    return Math.max(x, y);
  }

  private static int build(int a, int b) {
    int min = Math.min(a, b);
    int max = Math.max(a, b);
    max -= min;
    return min + (max >> 1);
  }

  /**
   * **********************************Helper Methods Begin
   * Here*********************************************
   */
  private static String reverse(String toRev) {
    return new StringBuilder(toRev).reverse().toString();
  }

  public static class Pair<F extends Comparable<F>, S extends Comparable<S>>
      implements Comparable<Pair<F, S>> {
    static final int prime = 31;
    private F first;
    private S second;

    public Pair(F f, S s) {
      this.first = f;
      this.second = s;
    }

    @Override
    public int hashCode() {
      int result = 1;
      result = prime * result + this.first.hashCode();
      result = prime * result + this.second.hashCode();
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;
      Pair<F, S> s = (Pair<F, S>) obj;
      return this.first.equals(s.first) && this.second.equals(s.second);
    }

    @Override
    public int compareTo(Pair<F, S> p) {
      int c1 = this.first.compareTo(p.first);
      if (c1 == 0) {
        return this.second.compareTo(p.second);
      }
      return c1;
    }
  }

  public static int swap(int a, int b) {
    /*a = Main.swap(b,b=a); goes from left to right*/
    return a;
  }

  public static long swap(long a, long b) {
    /*a = Main.swap(b,b=a); goes from left to right*/
    return a;
  }

  public static boolean next_permutation(int[] p) {
    for (int a = p.length - 2; a >= 0; --a)
      if (p[a] < p[a + 1])
        for (int b = p.length - 1; ; --b)
          if (p[b] > p[a]) {
            int t = p[a];
            p[a] = p[b];
            p[b] = t;
            for (++a, b = p.length - 1; a < b; ++a, --b) {
              t = p[a];
              p[a] = p[b];
              p[b] = t;
            }
            return true;
          }
    return false;
  }

  public static long gcd(long a, long b) {
    if (a < 0) a *= -1;
    if (b < 0) b *= -1;
    return b == 0 ? a : gcd(b, a % b);
  }

  public static class Reader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public Reader() {}

    public Reader initConsoleReading() {
      reader = new BufferedReader(new InputStreamReader(System.in), 32768);
      tokenizer = null;
      return this;
    }

    public Reader initFileReading(String filePath) throws FileNotFoundException {
      reader = new BufferedReader(new FileReader(filePath), 32768);
      tokenizer = null;
      return this;
    }

    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 String nextLine() throws IOException {
      return reader.readLine();
    }

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

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

    public void dispose() throws IOException {
      this.reader.close();
    }
  }
  /**
   * **********************************Helper Methods Ends
   * Here*********************************************
   */
}

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

public class Solve {

    int solve(int[] a) {
        Arrays.sort(a);
        return (int) Math.min(((long) a[0] + (long) a[1] + (long) a[2]) / 3L, a[0] + a[1]);
    }

    public static void main(String[] args) {
        Solve s = new Solve();
        // System.out.println(s.solve(new int[] {1000000000, 1000000000, 1000000000}));

        Scanner sc = new Scanner(System.in);
        int r = sc.nextInt();
        int g = sc.nextInt();
        int b = sc.nextInt();
        System.out.println(s.solve(new int[] {r, g, b}));
    }
}

import java.util.*;
import java.io.*;
public class table_decorations {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long a[] = new long[3];
		a[0] = sc.nextLong();
		a[1] = sc.nextLong();
		a[2] = sc.nextLong();

		Arrays.sort(a);
		if(a[0] == 0)
			System.out.println(0);
		else {
			long result = a[0];
			a[1]-=a[0];
			a[2]-=a[0];

			if(a[2]==1) {
				System.out.println(result);
			}
			else {
				long temp=0;
				if(a[1]%2==0)
					temp= a[1]/2;
				else
					temp=a[1]/2 +1;
				result+=temp;
				System.out.println(result);
			}
		}

	}

}

import java.io.*;    //PrintWriter
import java.math.*;  //BigInteger, BigDecimal
import java.util.*;  //StringTokenizer, ArrayList

public class R273_Div2_C
{
	FastReader in;
	PrintWriter out;

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

	void run()
	{
		in = new FastReader(System.in);
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	void solve()
	{
		long[] c = new long[3];
		c[0] = in.nextInt();
		c[1] = in.nextInt();
		c[2] = in.nextInt();
		long cnt = 0, sum = 0, n, min, x;

		while (1==1)
		{
			Arrays.sort(c);
			if (c[0] == 0 && c[1] == 0) break;
			sum = c[1] + c[2];
			if (c[2] >= sum * 2)
			{
				out.println(sum);
				break;
			}
			if (c[0] == 0)
			{
				sum = c[1] + c[2];
				cnt += Math.min(c[1], sum / 3);
				break;
			}
			n = c[2] / 2;
			sum = c[1] + c[0];
			min = Math.min(n,  sum);
			cnt += min;
			c[2] -= min*2;
			x = Math.min(min/2,  c[0]);
			c[0] -= x;
			c[1] -= (min - x);

			if (c[0] < 2 && c[1] < 2 && c[2] < 2) break;
		}
		if (c[0] == 1 && c[1] == 1 && c[2] == 1) cnt++;
		out.println(cnt);
	}

	//-----------------------------------------------------
	void runWithFiles() {
		in = new FastReader(new File("input.txt"));
		try {
			out = new PrintWriter(new File("output.txt"));
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		solve();
		out.close();
	}

	class FastReader
	{
	    BufferedReader br;
	    StringTokenizer tokenizer;

	    public FastReader(InputStream stream)
	    {
	        br = new BufferedReader(new InputStreamReader(stream));
	        tokenizer = null;
	    }
		public FastReader(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
				tokenizer = null;
			}
			catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

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

	    int nextInt() {
	        return Integer.parseInt(next());
	    }
	    long nextLong() {
	        return Long.parseLong(next());
	    }
	    double nextDouble() {
	        return Double.parseDouble(next());
	    }
	    BigInteger nextBigInteger() {
	        return new BigInteger(next());
	    }
	    BigDecimal nextBigDecimal() {
	        return new BigDecimal(next());
	    }
	}
}

import java.util.*;

public class C478{
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		long a[] = new long[3];
		a[0] = in.nextLong();
		a[1] = in.nextLong();
		a[2] = in.nextLong();

		Arrays.sort(a);

		if(2*(a[0]+1)<a[2])
			System.out.println(a[0]+a[1]);
		else
			System.out.println((a[0]+a[1]+a[2])/3);

	}
}

import java.io.*;
import java.util.*;
import java.math.*;
public class Test {
		public static void main(String[] args) {

		Scanner sc=new Scanner(System.in);
		int [] A = new int [3];
		for(int i = 0;i < 3;++i) A[i] = sc.nextInt();
		Arrays.sort(A);
		int ans = A[0];
		A[1] -= A[0];
		A[2] -= A[0];
		while(A[1] > 0) {
			int lo = 0,hi = A[1],x = 0;
			while(lo <= hi) {
				int mid = (lo+hi)/2;
				if(2*mid <= A[2]) {
					lo = mid+1;
					x = mid;
				}
				else hi = mid-1;
			}
			if(x == 0) break;
			A[1] -= x;
			A[2] -= (2*x);
			ans += x;
			if(A[1]>A[2]) {
				int tmp = A[1];
				A[1] = A[2];
				A[2] = tmp;
			}
		}
		System.out.println(ans);
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.StringTokenizer;
import java.io.Writer;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author zodiacLeo
 */
public class Main
{
    public static void main(String[] args)
    {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        FastScanner in = new FastScanner(inputStream);
        FastPrinter out = new FastPrinter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC
    {
        public void solve(int testNumber, FastScanner in, FastPrinter out)
        {
            int N = 3;
            int[] bags = new int[N];
            for (int i = 0; i < N; i++)
            {
                bags[i] = in.nextInt();
            }

            if (bags[0] == bags[1] && bags[1] == bags[2])
            {
                out.println(bags[0]);
                return;
            }
            int total = 0;
            int a = bags[0];
            int b = bags[1];
            int c = bags[2];
            if (a <= b)
            {
                int count1 = Math.min(a, b / 2);
                a -= count1;
                b -= 2 * count1;

                int count2 = 0;
                if (a <= c)
                {
                    count2 = Math.min(a, c / 2);
                    a -= count2;
                    c -= 2 * count2;
                } else if (a > c)
                {
                    count2 = Math.min(c, a / 2);
                    c -= count2;
                    a -= 2 * count2;
                }

                int count3 = 0;
                if (b <= c)
                {
                    count3 = Math.min(b, c / 2);
                    b -= count3;
                    c -= 2 * count3;
                } else if (b > c)
                {
                    count3 = Math.min(c, b / 2);
                    c -= count3;
                    a -= 2 * count3;
                }
                total = Math.max(total, count1 + count2 + count3);
            } else if (a > b)
            {
                int count1 = Math.min(b, a / 2);
                b -= count1;
                a -= 2 * count1;
                int count2 = 0;
                if (b <= c)
                {
                    count2 = Math.min(b, c / 2);
                    b -= count2;
                    c -= 2 * count2;
                } else if (b > c)
                {
                    count2 = Math.min(c, b / 2);
                    c -= count2;
                    b -= 2 * count2;
                }

                int count3 = 0;
                if (a <= c)
                {
                    count3 = Math.min(a, c / 2);
                } else if (a > c)
                {
                    count3 = Math.min(c, a / 2);
                }
                total = Math.max(total, count1 + count2 + count3);
            }

            a = bags[0];
            b = bags[1];
            c = bags[2];
            if (a <= c)
            {
                int count1 = Math.min(a, c / 2);
                a -= count1;
                c -= 2 * count1;

                int count2 = 0;
                if (a <= b)
                {
                    count2 = Math.min(a, b / 2);
                    a -= count2;
                    b -= 2 * count2;
                } else if (a > b)
                {
                    count2 = Math.min(b, a / 2);
                    b -= count2;
                    a -= 2 * count2;
                }

                int count3 = 0;
                if (b <= c)
                {
                    count3 = Math.min(b, c / 2);
                } else if (b > c)
                {
                    count3 = Math.min(c, b / 2);
                }
                total = Math.max(total, count1 + count2 + count3);
            } else if (a > c)
            {
                int count1 = Math.min(c, a / 2);
                c -= count1;
                a -= 2 * count1;

                int count2 = 0;
                if (b <= c)
                {
                    count2 = Math.min(b, c / 2);
                    b -= count2;
                    c -= 2 * count2;
                } else if (b > c)
                {
                    count2 = Math.min(c, b / 2);
                    c -= count2;
                    b -= count2 * 2;
                }

                int count3 = 0;
                if (a <= b)
                {
                    count3 = Math.min(a, b / 2);
                } else if (a > b)
                {
                    count3 = Math.min(b, a / 2);
                }
                total = Math.max(total, count1 + count2 + count3);
            }

            a = bags[0];
            b = bags[1];
            c = bags[2];
            if (b <= c)
            {
                int count1 = Math.min(b, c / 2);
                b -= count1;
                c -= 2 * count1;

                int count2 = 0;
                if (a <= b)
                {
                    count2 = Math.min(a, b / 2);
                    a -= count2;
                    b -= 2 * count2;
                } else if (a > b)
                {
                    count2 = Math.min(b, a / 2);
                    b -= count2;
                    a -= 2 * count2;
                }

                int count3 = 0;
                if (a <= c)
                {
                    count3 = Math.min(a, c / 2);
                } else if (a > c)
                {
                    count3 = Math.min(c, a / 2);
                }
                total = Math.max(total, count1 + count2 + count3);

            } else if (b > c)
            {
                int count1 = Math.min(c, b / 2);
                c -= count1;
                b -= 2 * count1;

                int count2 = 0;
                if (a <= b)
                {
                    count2 = Math.min(a, b / 2);
                    a -= count2;
                    b -= 2 * count2;
                } else if (a > b)
                {
                    count2 = Math.min(b, a / 2);
                    b -= count2;
                    a -= 2 * count2;
                }

                int count3 = 0;
                if (a <= c)
                {
                    count3 = Math.min(a, c / 2);
                    a -= count3;
                    c -= 2 * count3;
                } else if (a > c)
                {
                    count3 = Math.min(c, a / 2);
                    c -= count3;
                    a -= 2 * count3;
                }
                total = Math.max(total, count1 + count2 + count3);
            }
            out.println(total);
        }

    }

    static class FastScanner
    {
        BufferedReader br;
        StringTokenizer st;

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

        public FastScanner(File f)
        {
            try
            {
                br = new BufferedReader(new FileReader(f));
            } catch (FileNotFoundException e)
            {
                e.printStackTrace();
            }
        }

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

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

    }

    static class FastPrinter extends PrintWriter
    {
        public FastPrinter(OutputStream out)
        {
            super(out);
        }

        public FastPrinter(Writer out)
        {
            super(out);
        }

    }
}

//package javaapplication1;
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Main {

    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw=new PrintWriter(new PrintStream(System.out));
        String [] input=br.readLine().split(" ");
        long r=Long.parseLong(input[0]);
        long g=Long.parseLong(input[1]);
        long b=Long.parseLong(input[2]);
        List<Long>nums=new ArrayList<>();
        if(r!=0)
           nums.add(r);
        if(b!=0)
        nums.add(b);
        if(g!=0)
        nums.add(g);
        List<Long>numbers=new ArrayList<>();
        numbers.addAll(nums);
        long max,min,ans=0,elsum=0;
        nums.clear();
        while(numbers.size()>1)
        {
          elsum=0;
          nums.addAll(numbers);
          //simple algorithm is needed
          //first get the max /2 and add the rem and add min to it
          Collections.sort(nums);
          min=nums.get(0);
          max=nums.get(nums.size()-1);
           if(max==min&&nums.size()==3){
             System.out.println(ans+max);System.exit(0);
            }
           //if we have the max /2 as pairs >= min then we take it
           if(max/2>=min)
           {
               ans+=min;
               nums.set(0, (long)0);
               nums.set(nums.size()-1,max-(min*2));
           }
           else{
               ans+=max/2;
               nums.set(0,min-(max/2));
               nums.set(nums.size()-1,(max%2));
           }
           //System.out.println(nums);
           //filter
           numbers.clear();
            for (int i = 0; i < nums.size(); i++) {
                if(nums.get(i)!=0)
                { numbers.add(nums.get(i));elsum+=nums.get(i);}
            }
           nums.clear();
           if(elsum<3)
               break;
        }
            System.out.println(ans);
    }

}

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Test {
	public static void main(String[] args) {
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner(System.in);
		int[]data = new int[3];
		for(int i = 0; i < 3; i++){
			data[i] = in.nextInt();
		}
		Arrays.sort(data);
		long result = data[0];
		data[1] -= data[0];
		data[2] -= data[1];
		int min = Math.min(data[1], data[2]/2);
		result += min;
		out.println(result);

		out.close();
	}

}

import java.util.*;

import org.omg.CORBA.INTERNAL;

import java.awt.List;
import java.io.*;
import java.lang.*;
import java.lang.reflect.Array;

public class code3 {

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		// Code starts..

		long r = in.nextLong();
		long g = in.nextLong();
		long b = in.nextLong();

		long min = Math.min(r, Math.min(g, b));
		r -= min;
		g -= min;
		b -= min;
		long[] a = new long[3];
		a[0] = r;
		a[1] = g;
		a[2] = b;
		long ans = min;
		long n = -1;
		long m = -1;
		Arrays.sort(a);
		n = a[1];
		m = a[2];

		while(m+n>=3)
		{
			if(m<n)
			{
				long tmp = n;
				n = m;
				m = tmp;
			}

				if(2*n > m )
				{
					ans += m/2;
					n -= m/2;
					m -= 2*(m/2);
				}
				else
				{

					ans += n;
					n = 0;
				}
				pw.println(n +" "+m);

		}

		pw.println(ans);

		// code ends...

		pw.flush();
		pw.close();
	}

	public static double pow(double x, int n)
	{

		double ans = 1;
		for(int i=0; i<n; i++)
			ans *= x;
		return ans;
	}

	public static boolean check(String s1, String s2){

		boolean status = true;

        if(s1.length() != s2.length())
        {
            status = false;
        }
        else {
            char[] s1Array = s1.toLowerCase().toCharArray();

            char[] s2Array = s2.toLowerCase().toCharArray();
            Arrays.sort(s1Array);
            Arrays.sort(s2Array);
            status = Arrays.equals(s1Array, s2Array);
        }
        if(status)
        	return true;

        	return false;
    }

	public static long[][] mul(long[][] a, long[][] b){

		int n = a.length;
		int m = b[0].length;
		long[][] c = new long[n][m];

		for(int i=0; i<n; i++)
			for(int j=0; j<m; j++)
			{
				long tmp = 0;
				for(int k=0; k<a[0].length; k++)
					tmp =( (tmp+mod)%mod+(a[i][k]*b[k][j]+mod)%mod)%mod;
				c[i][j] = (tmp+mod)%mod;
			}

		return c;
	}

	public static long[][] pow(long[][] a,int  n)
	{

		long[][] res = a;
		while(n>0)
		{
			if(n%2==1)
			{
				res = mul(a, res);
			}

			a = mul(a, a);

			n/=2;

		}

		return res;

	}

	public static boolean isSubSequence(char[] str2, String str1) {

		int j = 0;
		int m = str1.length();
		int n = str2.length;

		for (int i = 0; i < n && j < m; i++)

			if (str1.charAt(j) == str2[i])

				j++;

		return (j == m);
	}

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

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

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

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

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

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}

	public static long c = 0;

	public static long mod = (long)Math.pow(10, 6)+3;
	public static int d;
	public static int p;
	public static int q;
	public static boolean flag;
	//public static long INF = Long.MAX_VALUE;

	public static void factSieve(int[] fact, long n) {

		for (int i = 2; i <= n; i += 2)
			fact[i] = 2;

		for (int i = 3; i <= n; i += 2) {
			if (fact[i] == 0) {
				fact[i] = i;

				for (int j = i; (long) j * i <= n; j++) {
					fact[(int) ((long) i * j)] = i;
				}
			}
		}

		/*
		 * int k = 1000; while(k!=1) { System.out.print(a[k]+" "); k /= a[k];
		 *
		 * }
		 */
	}

	public static long floorsqrt(long n) {
		long ans = 0;
		long l = 0;
		long r = n;
		long mid = 0;
		while (l <= r) {
			mid = (l + r) / 2;
			if (mid * mid == n)
				return mid;

			if (mid * mid > n) {
				r = mid - 1;
			} else {
				ans = mid;
				l = mid + 1;
			}

		}

		return ans;
	}

	public static long fun(int[] a, int[] b, int m, int n) {
		long result = 0;
		for (int i = 0; i < m; i++)
			for (int j = 0; j < m; j++) {
				long[] fib = new long[Math.max(2, n + 2)];
				fib[1] = a[i];
				fib[2] = b[j];
				for (int k = 3; k <= n; k++)
					fib[k] = (fib[k - 1] % mod + fib[k - 2] % mod) % mod;
				result = (result % mod + fib[n] % mod) % mod;
			}

		return result;

	}

	/*
	 * public static double slope(pair p1, pair p2) { double m = INF; if((p1.x -
	 * p2.x)!=0) m = p1.y - p2.y/(p1.x - p2.x);
	 *
	 *
	 * return Math.abs(m);
	 *
	 * }
	 */

	public static int gcd(int p2, int p22) {
		if (p2 == 0)
			return (int) p22;
		return gcd(p22 % p2, p2);
	}

	public static int findGCD(int arr[], int n) {
		int result = arr[0];
		for (int i = 1; i < n; i++)
			result = gcd(arr[i], result);

		return result;
	}

	public static void nextGreater(long[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] < a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] >= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static void nextGreaterRev(long[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] < arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] >= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmallerRev(int[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] > arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] <= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmaller(int[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] > a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] <= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static long lcm(int[] numbers) {
		long lcm = 1;
		int divisor = 2;
		while (true) {
			int cnt = 0;
			boolean divisible = false;
			for (int i = 0; i < numbers.length; i++) {
				if (numbers[i] == 0) {
					return 0;
				} else if (numbers[i] < 0) {
					numbers[i] = numbers[i] * (-1);
				}
				if (numbers[i] == 1) {
					cnt++;
				}
				if (numbers[i] % divisor == 0) {
					divisible = true;
					numbers[i] = numbers[i] / divisor;
				}
			}
			if (divisible) {
				lcm = lcm * divisor;
			} else {
				divisor++;
			}
			if (cnt == numbers.length) {
				return lcm;
			}
		}
	}

	public static long fact(long n) {

		long factorial = 1;
		for (int i = 1; i <= n; i++) {
			factorial *= i;
		}
		return factorial;
	}

	public static int lowerLimit(int[] a, int n) {
		int ans = 0;

		int ll = 0;
		int rl = a.length - 1;
		// System.out.println(a[rl]+" "+n);
		if (a[0] > n)
			return 0;
		if (a[0] == n)
			return 1;
		else if (a[rl] <= n)
			return rl + 1;

		while (ll <= rl) {

			int mid = (ll + rl) / 2;
			if (a[mid] == n) {
				ans = mid + 1;
				break;
			}

			else if (a[mid] > n) {
				rl = mid - 1;

			} else {
				ans = mid + 1;
				ll = mid + 1;
			}
		}

		return ans;
	}

	public static long choose(long total, long choose) {
		if (total < choose)
			return 0;
		if (choose == 0 || choose == total)
			return 1;
		return (choose(total - 1, choose - 1) + choose(total - 1, choose)) % mod;
	}

	public static int[] suffle(int[] a, Random gen) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}
		return a;
	}

	public static int floorSearch(int arr[], int low, int high, int x) {
		if (low > high)
			return -1;

		if (x > arr[high])
			return high;
		int mid = (low + high) / 2;

		if (mid > 0 && arr[mid - 1] < x && x < arr[mid])
			return mid - 1;

		if (x < arr[mid])
			return floorSearch(arr, low, mid - 1, x);

		return floorSearch(arr, mid + 1, high, x);
	}

	public static void swap(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
	}

	public static ArrayList<Integer> primeFactorization(int n) {
		ArrayList<Integer> a = new ArrayList<Integer>();
		for (int i = 2; i * i <= n; i++) {
			while (n % i == 0) {
				a.add(i);
				n /= i;
			}
		}
		if (n != 1)
			a.add(n);
		return a;
	}

	public static void sieve(boolean[] isPrime, int n) {
		for (int i = 1; i < n; i++)
			isPrime[i] = true;

		isPrime[0] = false;
		isPrime[1] = false;

		for (int i = 2; i * i < n; i++) {
			if (isPrime[i] == true) {
				for (int j = (2 * i); j < n; j += i)
					isPrime[j] = false;
			}
		}
	}

	public static int lowerbound(ArrayList<Long> net, long c2) {
		int i = Collections.binarySearch(net, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int lowerboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int uperbound(ArrayList<Integer> list, int c2) {
		int i = Collections.binarySearch(list, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static int uperboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static long[] sort(long[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			long temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int[] sort(int[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int GCD(int a, int b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static void extendedEuclid(int A, int B) {
		if (B == 0) {
			d = A;
			p = 1;
			q = 0;
		} else {
			extendedEuclid(B, A % B);
			int temp = p;
			p = q;
			q = temp - (A / B) * q;
		}
	}

	public static long LCM(long a, long b) {
		return (a * b) / GCD(a, b);
	}

	public static int LCM(int a, int b) {
		return (a * b) / GCD(a, b);
	}

	public static int binaryExponentiation(int x, int n) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = x * x;
			n = n / 2;
		}
		return result;
	}

	public static int[] countDer(int n) {
		int der[] = new int[n + 1];

		der[0] = 1;
		der[1] = 0;
		der[2] = 1;

		for (int i = 3; i <= n; ++i)
			der[i] = (i - 1) * (der[i - 1] + der[i - 2]);

		// Return result for n
		return der;
	}

	static long binomialCoeff(int n, int k) {
		long C[][] = new long[n + 1][k + 1];
		int i, j;

		// Calculate value of Binomial Coefficient in bottom up manner
		for (i = 0; i <= n; i++) {
			for (j = 0; j <= Math.min(i, k); j++) {
				// Base Cases
				if (j == 0 || j == i)
					C[i][j] = 1;

				// Calculate value using previosly stored values
				else
					C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
			}
		}

		return C[n][k];
	}

	public static long binaryExponentiation(long x, long n) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = (x % mod * x % mod) % mod;
			n = n / 2;
		}
		return result;
	}

	public static int modularExponentiation(int x, int n, int M) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static long modularExponentiation(long x, long n, long M) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static int modInverse(int A, int M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static long sie(long A, long M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static boolean checkYear(int year) {
		if (year % 400 == 0)
			return true;

		if (year % 100 == 0)
			return false;

		if (year % 4 == 0)
			return true;
		return false;
	}

	public static boolean isPrime(int n) {

		if (n <= 1)
			return false;
		if (n <= 3)
			return true;

		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6) {
			if (n % i == 0 || n % (i + 2) == 0)
				return false;
		}

		return true;
	}

	static class pair implements Comparable<pair>

	{
		Long x, y;

		pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		public int compareTo(pair o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);

			return result;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Object o) {
			if (o instanceof pair) {
				pair p = (pair) o;
				if(p.x-x==0 && p.y-y==0)
					return true;
				else
				return false;
			}
			return false;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
		}

	}

	static class triplet implements Comparable<triplet> {
		Integer x, y, z;

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

		public int compareTo(triplet o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);
			if (result == 0)
				result = z.compareTo(o.z);

			return result;
		}

		public boolean equlas(Object o) {
			if (o instanceof triplet) {
				triplet p = (triplet) o;
				return x == p.x && y == p.y && z == p.z;
			}
			return false;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode() + new Long(z).hashCode();
		}
	}

	static class query implements Comparable<query> {
		Integer l,r, x, idx, tp;

		query(int l, int r, int x, int id, int tp)
		{
			this.l = l ;
			this.r = r;
			this.x = x;
			this.idx = id;
			this.tp = tp;
		}

		public int compareTo(query o) {
			int result = x.compareTo(o.x);

			return result;
		}

	}

	/*
	 * static class node implements Comparable<node>
	 *
	 * { Integer x, y, z; node(int x,int y, int z) { this.x=x; this.y=y; this.z=z; }
	 *
	 * public int compareTo(pair o) { int result = x.compareTo(o.x); if(result==0)
	 * result = y.compareTo(o.y); if(result==0) result = z.compareTo(z); return
	 * result; }
	 *
	 * @Override public int compareTo(node o) { // TODO Auto-generated method stub
	 * return 0; } }
	 */
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 *
 * @author pttrung
 */
public class C_Round_273_Div2 {

	public static long MOD = 1000000007;

	public static void main(String[] args) throws FileNotFoundException {
		// PrintWriter out = new PrintWriter(new FileOutputStream(new File(
		// "output.txt")));
		PrintWriter out = new PrintWriter(System.out);
		Scanner in = new Scanner();
		long[] data = new long[3];
		for (int i = 0; i < 3; i++) {
			data[i] = in.nextInt();
		}
		Arrays.sort(data);
		long start = 0;
		long end = data[0];
		long result = 0;
		while (start <= end) {
			long mid = (start + end) >> 1L;

			long a = max(mid, data);
			long b = max(mid + 2, data);
			// System.out.println(a + " " + b + " " + mid);
			if (a > b) {
				result = result > a ? result : a;
				end = mid - 1;
			} else {
				result = result > b ? result : b;
				start = mid + 1;
			}
		}
//		for (int i = 0; i <= data[0]; i++) {
//			long v = max(i, data);
//			System.out.println(v + " " + i);
//
//			if (v > result) {
//				result = v;
//			}
//		}
		out.println(result);
		out.close();
	}

	static long max(long mid, long[] data) {
		long x = data[0] - mid;
		long y = data[1] - mid;
		long z = data[2] - mid;
		long result = mid;
		long[] tmp = { x, y, z };
		while (true) {
			Arrays.sort(tmp);
			long v = 0;
			if (tmp[0] != 0) {
				v = (tmp[2] / 2 > tmp[0] ? tmp[0] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[0] -= v;
			} else {
				v = (tmp[2] / 2 > tmp[1] ? tmp[1] : tmp[2] / 2);
				tmp[2] -= 2 * v;
				tmp[1] -= v;
			}
			result += v;
			if (v == 0) {
				break;
			}
		}
		return result;

	}

	public static int[] KMP(String val) {
		int i = 0;
		int j = -1;
		int[] result = new int[val.length() + 1];
		result[0] = -1;
		while (i < val.length()) {
			while (j >= 0 && val.charAt(j) != val.charAt(i)) {
				j = result[j];
			}
			j++;
			i++;
			result[i] = j;
		}
		return result;

	}

	public static boolean nextPer(int[] data) {
		int i = data.length - 1;
		while (i > 0 && data[i] < data[i - 1]) {
			i--;
		}
		if (i == 0) {
			return false;
		}
		int j = data.length - 1;
		while (data[j] < data[i - 1]) {
			j--;
		}
		int temp = data[i - 1];
		data[i - 1] = data[j];
		data[j] = temp;
		Arrays.sort(data, i, data.length);
		return true;
	}

	public static int digit(long n) {
		int result = 0;
		while (n > 0) {
			n /= 10;
			result++;
		}
		return result;
	}

	public static double dist(long a, long b, long x, long y) {
		double val = (b - a) * (b - a) + (x - y) * (x - y);
		val = Math.sqrt(val);
		double other = x * x + a * a;
		other = Math.sqrt(other);
		return val + other;

	}

	public static class Point implements Comparable<Point> {

		int x, y;

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

		@Override
		public int hashCode() {
			int hash = 5;
			hash = 47 * hash + this.x;
			hash = 47 * hash + this.y;
			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj == null) {
				return false;
			}
			if (getClass() != obj.getClass()) {
				return false;
			}
			final Point other = (Point) obj;
			if (this.x != other.x) {
				return false;
			}
			if (this.y != other.y) {
				return false;
			}
			return true;
		}

		@Override
		public int compareTo(Point o) {
			return x - o.x;
		}
	}

	public static class FT {

		long[] data;

		FT(int n) {
			data = new long[n];
		}

		public void update(int index, long value) {
			while (index < data.length) {
				data[index] += value;
				index += (index & (-index));
			}
		}

		public long get(int index) {
			long result = 0;
			while (index > 0) {
				result += data[index];
				index -= (index & (-index));
			}
			return result;

		}
	}

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

	public static long pow(long a, long b) {
		if (b == 0) {
			return 1;
		}
		if (b == 1) {
			return a;
		}
		long val = pow(a, b / 2);
		if (b % 2 == 0) {
			return val * val % MOD;
		} else {
			return val * (val * a % MOD) % MOD;

		}
	}

	static class Scanner {

		BufferedReader br;
		StringTokenizer st;

		public Scanner() throws FileNotFoundException {
			// System.setOut(new PrintStream(new
			// BufferedOutputStream(System.out), true));
			br = new BufferedReader(new InputStreamReader(System.in));
			// br = new BufferedReader(new InputStreamReader(new
			// FileInputStream(new File("input.txt"))));
		}

		public String next() {

			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception e) {
					throw new RuntimeException();
				}
			}
			return st.nextToken();
		}

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

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

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

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

		public boolean endLine() {
			try {
				String next = br.readLine();
				while (next != null && next.trim().isEmpty()) {
					next = br.readLine();
				}
				if (next == null) {
					return true;
				}
				st = new StringTokenizer(next);
				return st.hasMoreTokens();
			} catch (Exception e) {
				throw new RuntimeException();
			}
		}
	}
}

import java.util.Scanner;
public class TableDecorations {

    public static void main(String[] args) {
        Scanner input= new Scanner(System.in);
        int r, b, g, s=0;
        r=input.nextInt();
        b=input.nextInt();
        g=input.nextInt();
        s=b+g+r;
        s/=3;
        if(r>b){
            if(r>g)
                r=0;}
        else
                if(b>g)
                    b=0;
        else
                    g=0;
        if(s> (b+g+r))
            System.out.println(b+g+r);
        else
            System.out.println(s);
    }
}

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

public class Solution{

	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int[] arr = new int[3];
		for(int i = 0; i < 3; i++)
			arr[i] = sc.nextInt();

		Arrays.sort(arr);

		System.out.println(Math.max(arr[0]+arr[1], (arr[0]+arr[1]+arr[2])/3));
	}
}

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

public class C478 {

	public static void main(String[] args) throws NumberFormatException, IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] a = br.readLine().split(" ");
		int r = Integer.parseInt(a[0]);
		int g = Integer.parseInt(a[1]);
		int b = Integer.parseInt(a[2]);

		int min = Math.min(r , Math.min(g,b));
		long tt = min;
		r = r - min;
		g = g-min;
		b = b-min;

		if(r + g + b < 3){
			System.out.println(tt);
			return;
		}
		if(r == 0){
			if(g >= b){
				int tmp=g/2;
				tt += tmp;
				g = g-2*tmp;
				b = b-tmp;

			}

			if(g < b && g!=0){
				tt += b/2;
			}

		}
		else if(b == 0){
			if(g >= r){
				int tmp=g/2;
				tt += tmp;
				g = g-2*tmp;
				r = r-tmp;

			}

			if(g < r && g != 0){
				tt += r/2;
			}

		}else {
			if(r >= b){
				int tmp=r/2;
				tt += tmp;
				r = r-2*tmp;
				b = b-tmp;

			}

			if(r < b && r!= 0){
				tt += b/2;
			}

		}

		System.out.println(tt);
	}
}

/* package whatever; // don't place package name! */

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

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Scanner sc = new Scanner(System.in);
        long a[] = new long[3];
        for(int i = 0;i<3;i++){
            a[i]=sc.nextLong();
        }
        Arrays.sort(a);
        long r = a[0];
        long g = a[1];
        long b = a[2];
        System.out.println(Math.min((r+g+b)/3,Math.min((r+g)/2,g+b)));
    }
}

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

public class Decorations {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scn=new Scanner(System.in);
		long []a=new long[3];
		a[0]=scn.nextLong();
		a[1]=scn.nextLong();
		a[2]=scn.nextLong();
		Arrays.sort(a);
		long sum=a[0];
		a[0]=0;
		a[1]-=sum;
		a[2]-=sum;
		long x=(a[1]+a[2])/3;
		if(x>=3) {
			System.out.println(sum+3);
		}else {
			System.out.println(sum+x);
		}
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.StringTokenizer;

public class Algoritm {
	public static void main(String[] args) {
		// try {
		// InputStream inputStream = new FileInputStream(
		// "D:\\google\\workjem\\googlejam\\input.txt");
		// OutputStream outputStream = new FileOutputStream(
		// "D:\\google\\workjem\\googlejam\\output.txt");
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		C solver = new C();
		// int t = in.nextInt();
		// for (int i = 1; i <= t; i++) {
		solver.solve(1, in, out);
		// }
		out.close();
		// } catch (FileNotFoundException e) {
		// e.printStackTrace();
		// } catch (IOException e) {
		// e.printStackTrace();
		// }
	}
}

class C {

	public void solve(int testNumber, InputReader in, PrintWriter out) {

		int[] a = new int[3];
		int sum = 0;
		for (int i = 0 ;i < 3; i++){
			a[i] = in.nextInt();
			sum+= a[i];
		}
		Arrays.sort(a);
		//System.out.println(Arrays.toString(a));
		//System.out.println(sum);
		sum-= Math.max(0, a[2] - (a[0]+a[1])*2);
		System.out.println(sum/3);
		// System.out.println(Arrays.toString(a));
		// System.out.println(cap + " = " + sum + " " + n);
		// out.println("Case #" + testNumber + ": " + sum);
	}

	boolean transection(double ax1, double ay1, double ax2, double ay2,
			double bx1, double by1, double bx2, double by2) {
		double v1 = (bx2 - bx1) * (ay1 - by1) - (by2 - by1) * (ax1 - bx1);
		double v2 = (bx2 - bx1) * (ay2 - by1) - (by2 - by1) * (ax2 - bx1);
		double v3 = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
		double v4 = (ax2 - ax1) * (by2 - ay1) - (ay2 - ay1) * (bx2 - ax1);
		return ((v1 * v2 <= 0) && (v3 * v4 <= 0));
	}

	class Pair implements Comparable<Pair> {
		// ArrayList<Pair> p = new ArrayList<Pair>();
		// Collections.sort(p, Comparators.AGE);
		int r;

		int x;
		int y;
		int color;

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

		public boolean check(int x, int y) {
			boolean good = true;
			if (x >= this.x && y >= this.y) {
				good = false;
			}
			return good;
		}

		@Override
		public int compareTo(Pair o) {
			return Comparators.AGE.compare(this, o);
		}

		public String toString() {
			return "" + x + " " + y;
		}

	}

	public static class Comparators {

		public static Comparator<Pair> AGE = new Comparator<Pair>() {
			@Override
			public int compare(Pair o1, Pair o2) {
				if (o1.x == o2.x) {
					return o1.y < o2.y ? 1 : -1;
				}
				return o1.x < o2.x ? 1 : -1;
			}
		};
	}
}

class InputReader {

	public BufferedReader reader;
	public StringTokenizer tokenizer;

	public InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		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 int nextInt() {
		return Integer.parseInt(next());
	}

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

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

	public String nextString() {
		return next();
	}

}

import java.util.Scanner;

public class Main {

    public static int max(int r, int g, int b) {
        //int m = 0;
        if (r > g) {
            if(r > b) {
                return r;
            } else {
                return b;
            }
        } else {
            if(g > b) {
                return g;
            } else {
                return b;
            }
        }
    }
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin = new Scanner(System.in);
        int r = cin.nextInt();
        int g = cin.nextInt();
        int b = cin.nextInt();
        int m = max(r, g, b);
        int result = 0;
        if(m > 2 * (r + g + b - m)) {
            result = ((r + g + b) - (m - 2 * (r + g + b - m)))/3;
        } else {
            result = (r + g + b)/3;
        }

        System.out.println(result);

    }

}

import java.util.Scanner;

public class A {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();
        if (a < b) {
            int temp = a;
            a = b;
            b = temp;
        }
        if (a < c) {
            int temp = a;
            a = c;
            c = temp;
        }
        if (b < c) {
            int temp = c;
            c = b;
            b = temp;
        }
        // a > b > c
        long res = getRes(a, b, c);
        System.out.println(res);
    }

    private static long getRes(int a, int b, int c) {
        int left = 0;
        long res = 0;

        int pairs = a / 2;
        left += a % 2;

        res += Math.min((pairs / 2) + (pairs % 2), b);
        b -= (pairs / 2) + (pairs % 2);
        if (b < 0)
            b = 0;
        left += b;

        res += Math.min((pairs / 2), c);
        c -= (pairs / 2);
        if (c < 0)
            c = 0;
        left += c;

        return res + (left / 3);
    }
}

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

public class Main {
	InputReader scn;
	PrintWriter out;
	String INPUT = "";

	void solve() {
		int[] arr = {scn.nextInt(), scn.nextInt(), scn.nextInt()};
		Arrays.sort(arr);

		long ans = arr[0];
		arr[1] -= arr[0];
		arr[2] -= arr[0];

		int diff = arr[2] - arr[1];
		arr[1] -= diff;
		arr[2] -= 2 * diff;
		if(arr[1] < 0) {
			ans += arr[1];
		} else {
			ans += diff;
			ans += (arr[1] + arr[2]) / 3;
		}

		out.println(ans);
	}

	void run() throws Exception {
		boolean onlineJudge = System.getProperty("ONLINE_JUDGE") != null;
		out = new PrintWriter(System.out);
		scn = new InputReader(onlineJudge);
		long time = System.currentTimeMillis();
		solve();
		out.flush();
		if (!onlineJudge) {
			System.out.println(Arrays.deepToString(new Object[] { System.currentTimeMillis() - time + " ms" }));
		}
	}

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

	class InputReader {
		InputStream is;

		public InputReader(boolean onlineJudge) {
			is = onlineJudge ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		}

		byte[] inbuf = new byte[1024];
		public int lenbuf = 0, ptrbuf = 0;

		int readByte() {
			if (lenbuf == -1)
				throw new InputMismatchException();
			if (ptrbuf >= lenbuf) {
				ptrbuf = 0;
				try {
					lenbuf = is.read(inbuf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (lenbuf <= 0)
					return -1;
			}
			return inbuf[ptrbuf++];
		}

		boolean isSpaceChar(int c) {
			return !(c >= 33 && c <= 126);
		}

		int skip() {
			int b;
			while ((b = readByte()) != -1 && isSpaceChar(b))
				;
			return b;
		}

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

		char nextChar() {
			return (char) skip();
		}

		String next() {
			int b = skip();
			StringBuilder sb = new StringBuilder();
			while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
				sb.appendCodePoint(b);
				b = readByte();
			}
			return sb.toString();
		}

		char[] next(int n) {
			char[] buf = new char[n];
			int b = skip(), p = 0;
			while (p < n && !(isSpaceChar(b))) {
				buf[p++] = (char) b;
				b = readByte();
			}
			return n == p ? buf : Arrays.copyOf(buf, p);
		}

		int nextInt() {
			int num = 0, b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		long nextLong() {
			long num = 0;
			int b;
			boolean minus = false;
			while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
				;
			if (b == '-') {
				minus = true;
				b = readByte();
			}

			while (true) {
				if (b >= '0' && b <= '9') {
					num = num * 10 + (b - '0');
				} else {
					return minus ? -num : num;
				}
				b = readByte();
			}
		}

		char[][] nextMatrix(int n, int m) {
			char[][] map = new char[n][];
			for (int i = 0; i < n; i++)
				map[i] = next(m);
			return map;
		}

		int[] nextArray(int n, boolean isOneInd) {
			int k = isOneInd ? 1 : 0;
			int[] a = new int[n + k];
			for (int i = k; i < n + k; i++)
				a[i] = nextInt();
			return a;
		}

		int[] shuffle(int[] arr) {
			Random r = new Random();
			for (int i = 1, j; i < arr.length; i++) {
				j = r.nextInt(i);
				arr[i] = arr[i] ^ arr[j];
				arr[j] = arr[i] ^ arr[j];
				arr[i] = arr[i] ^ arr[j];
			}
			return arr;
		}
	}
}

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

public class Main {
    public static void main(String[] args) throws IOException {
        Scan s = new Scan();
        int r = s.scanInt();
        int g = s.scanInt();
        int b = s.scanInt();
        System.out.println(solve(r,g,b));
    }

    private static long solve(int r,int g,int b){
       long[] arr = {r,g,b};
       long ans = 0;
       Arrays.sort(arr);

       while(true){
           if(arr[0] + arr[1] + arr[2] < 3 || arr[0] == 0 && arr[1] == 0) break;
           if(arr[0] == 1 && arr[1] == 1 && arr[2] == 1 && ++ans > 0) break;
           long pairs = arr[2] / 2;
           long possible_pairs = Math.min(arr[1],pairs);
           ans += possible_pairs;
           arr[1] -= possible_pairs;
           arr[2] -= possible_pairs * 2;
           Arrays.sort(arr);
       }

       return ans;
    }
}

class Scan
{
    private byte[] buf=new byte[1024];    //Buffer of Bytes
    private int index;
    private InputStream in;
    private int total;
    public Scan()
    {
        in=System.in;
    }
    public int scan()throws IOException    //Scan method used to scan buf
    {
        if(total<0)
        throw new InputMismatchException();
        if(index>=total)
        {
            index=0;
            total=in.read(buf);
            if(total<=0)
            return -1;
        }
        return buf[index++];
    }
    public int scanInt()throws IOException
    {
        int integer=0;
        int n=scan();
        while(isWhiteSpace(n))    //Removing starting whitespaces
        n=scan();
        int neg=1;
        if(n=='-')                //If Negative Sign encounters
        {
            neg=-1;
            n=scan();
        }
        while(!isWhiteSpace(n))
        {
            if(n>='0'&&n<='9')
            {
                integer*=10;
                integer+=n-'0';
                n=scan();
            }
            else throw new InputMismatchException();
        }
        return neg*integer;
    }
    private boolean isWhiteSpace(int n)
    {
        if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
        return true;
        return false;
    }
}

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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        Reader in = new Reader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, Reader in, PrintWriter out) {
            long[] balls = new long[3];
            for (int i = 0; i < 3; ++i)
                balls[i] = in.nextInt();

            Arrays.sort(balls);

            if ((long) balls[0] + balls[1] <= balls[2]) {
                out.println(Math.min((2 * (long) balls[2] / 3), (long) balls[0] + balls[1]));
                return;
            } else {
                long res = balls[0];
                balls[1] -= balls[0];
                balls[2] -= balls[0];

                if (balls[1] * 2 <= balls[2]) {
                    res += balls[1];
                    out.println(res);
                    return;
                }

                long dif = balls[2] - balls[1];

                res += dif;
                balls[1] -= dif;
                res += 2 * (balls[1] / 3);

                if (balls[1] % 3 == 2) ++res;
                out.println(res);
            }
        }

    }

    static class Reader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public Reader(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 int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

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

public class SolutionC2 {
    public void solve() throws Exception{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(System.out);
        String s[] = bf.readLine().split(" ");
        int c[] = new int[3];
        int t = 0;
        c[0] = Integer.parseInt(s[0]);c[1] = Integer.parseInt(s[1]);c[2] = Integer.parseInt(s[2]);
        Arrays.sort(c);
        while(c[0]+c[1]+c[2]>=3 && (c[0]!=0 || c[1]!=0)){
            int i = Math.min(c[2]/2, c[0]+c[1]);
            if(i==0){
                t++;
                break;
            }
            c[2] -=2*i;
            if(c[1]>=i)
                c[1]-=i;
            else{
                c[0] -=(i-c[1]);
                c[1] = 0;
            }
            Arrays.sort(c);
            t += i;

        }
        out.println(t);
        out.flush();
    }
    public static void main(String args[]) throws Exception{
        new SolutionC2().solve();
    }

}

import java.util.*;

public class Main{

    public static void main(String[] args) {
       Scanner input=new Scanner(System.in);
       long r=input.nextInt();
       long g=input.nextInt();
       long b=input.nextInt();
       long s=(r+g+b)/3;
       long max;
       if(r>g){
           if(g>b)
               max=r;
           else if(r>b)
                    max=r;
                else
                    max=b;
       }
       else
           if(g>b)
               max=g;
           else
               max=b;
        if(s>max)
            System.out.println(max);
        else
            System.out.println(s);
  }
}

/*

LANG: JAVA
TASK: combo
 */
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Random;

public class combo
{
	public static void main(String[] args) throws Exception
	{
		BufferedReader bR = new BufferedReader(new InputStreamReader(System.in));
		int[] thing = readInt(bR);
		Arrays.sort(thing);
		int thingy = thing[0]+thing[1]+thing[2];
		thingy/=3;

		if(thing[0]+thing[1]<thingy)
		{
			thingy = thing[0]+thing[1];
		}
		System.out.println(thingy);
	}

	static long fibbonaci(int n)
	{
		if(n<2)
		{
			return 1;
		}
		return fibbonaci(n-1)+fibbonaci(n-2);
	}

	static int findMinDiff(int[] array)
	{
		int min = Integer.MAX_VALUE;
		for(int a = 0;a<array.length-1;a++)
		{
			min = Math.min(min,array[a+1]-array[a]);
		}
		return min;
	}

	static int numUppercase(String a)
	{
		int num = 0;
		char[] thing = a.toCharArray();
		for(char c: thing)
		{
			if(c>='A'&&c<='Z')
			{
				num++;
			}
		}
		return num;
	}

	static char whichChar(char[][] array, int startX,int endX, int startY, int endY)
	{
		char test = array[startY][startX];
		for(int x = startX;x<endX;x++)
		{
			for(int y = startY;y<endY;y++)
			{
				if(array[y][x]!=test)
				{
					return '-';
				}
			}
		}
		return test;
	}

	public static void shuffle(int[] array)
	{
		Random random = new Random();
		for (int i = array.length - 1; i > 0; i--)
		{
			int index = random.nextInt(i + 1);

			int temp = array[index];
			array[index] = array[i];
			array[i] = temp;
		}
	}

	public static int[] readInt(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		int[] readArr = new int[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Integer.parseInt(temp[a]);
		}
		return readArr;
	}

	public static double[] readDouble(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		double[] readArr = new double[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Double.parseDouble(temp[a]);
		}
		return readArr;
	}

	public static long[] readLong(BufferedReader bR) throws Exception
	{
		String temp[] = bR.readLine().split(" ");
		long[] readArr = new long[temp.length];
		for (int a = 0; a < temp.length; a++)
		{
			readArr[a] = Long.parseLong(temp[a]);
		}
		return readArr;
	}
}

import java.util.*;
import java.io.*;
import java.math.*;
public class Main{
	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	public static void main(String sp[])throws IOException{
		//Scanner sc = new Scanner(System.in);
		FastReader sc = new FastReader();
		long r = sc.nextInt();
		long g = sc.nextInt();
		long b = sc.nextInt();
		ArrayList<Long> al = new ArrayList<>();
		al.add(r);
		al.add(g);
		al.add(b);
		Collections.sort(al);
		if(al.get(1)+al.get(0)>=al.get(2)){
			System.out.println((r+g+b)/3);
		}else{
			System.out.println(al.get(1)+al.get(0));
		}

	}

	public static int power(int x, int y)
	{
		int temp;
		if( y == 0)
			return 1;
		temp = power(x, y/2);
		if (y%2 == 0)
			return temp*temp;
		else
			return x*temp*temp;
	}

	public static ArrayList<Integer> comp(){
		ArrayList<Integer> al = new ArrayList<>();
			int n = (int)2e5;
			boolean arr[] = new boolean[n+1];
			int sqrt = (int)Math.sqrt(n);
			for(int i=2;i<=sqrt;i++){
				if(arr[i]==false){
					for(int j=i*i;j<=n;j+=i){
						arr[j]=true;
					}
				}
			}
			for(int i=2;i<=n;i++){
				if(arr[i]==false)
					al.add(i);
			}

		return al;
	}

	public static class pair{
		int x;
		int y;
	}

	public static class comp implements Comparator<pair>{
		public int compare(pair o1, pair o2){
			if(o1.x==o2.x){
				return o1.y-o2.y;
			}
			return o1.x-o2.x;
		}
	}

	static HashMap<Integer,Integer> visited = new HashMap<>();

	static class Node{
		int node;
		int d;
		ArrayList<Integer> al = new ArrayList<>();
	}

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

	static class FastReader
		{
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public FastReader()
		{
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public FastReader(String file_name) throws IOException
		{
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String readLine() throws IOException
		{
			byte[] buf = new byte[64]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1)
			{
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException
		{
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do
			{
				ret = ret * 10 + c - '0';
			}  while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException
		{
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException
		{
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			}
			while ((c = read()) >= '0' && c <= '9');

			if (c == '.')
			{
				while ((c = read()) >= '0' && c <= '9')
				{
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException
		{
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException
		{
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException
		{
			if (din == null)
				return;
			din.close();
		}
	}
}

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

import static java.lang.Math.*;

public class Main {
    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        long a = nextInt();
        long b = nextInt();
        long c = nextInt();
        long ans = min((a + b + c) / 3, max(a, max(b, c)));
        pw.println(ans);
        pw.close();
    }

    static long mod = 1_000_000_007;

    static StringTokenizer st = new StringTokenizer("");
    static BufferedReader br;

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

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

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

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

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

public class C{
	public static void main(String[] args)throws IOException{
		Scanner sc=new Scanner(System.in);
		int A[]=new int[3];

		for(int i=0;i<3;i++)A[i]=sc.nextInt();

			Arrays.sort(A);
				int res=0;
				res+=A[0];

				A[1]-=A[0];
				A[2]-=A[0];
				A[0]=0;

				if(A[2]-A[1]>A[1]){
					res+=A[1];
					A[2]-=A[1];
					A[1]=0;
					System.out.println(res);
					return;
				}
				else if((A[1]>A[2]-A[1])&&(A[1]!=A[2])){
					res+=A[2]-A[1];
					A[0]=2*A[1]-A[2];
					A[1]=A[0];
					A[2]=0;
					Arrays.sort(A);
				}

				if(A[2]==1)res=res;
				else if(A[2]%2==1)res+=(A[2]/2)+1;
				else res+=A[2]/2;

				System.out.println(res);
	}
}

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

public class C {

	static class Scanner{
		BufferedReader br=null;
		StringTokenizer tk=null;
		public Scanner(){
			br=new BufferedReader(new InputStreamReader(System.in));
		}
		public String next() throws IOException{
			while(tk==null || !tk.hasMoreTokens())
				tk=new StringTokenizer(br.readLine());
			return tk.nextToken();
		}
		public int nextInt() throws NumberFormatException, IOException{
			return Integer.valueOf(next());
		}
		public long nextLong() throws NumberFormatException, IOException{
			return Long.valueOf(next());
		}
		public double nextDouble() throws NumberFormatException, IOException{
			return Double.valueOf(next());
		}
	}

	static long[] a;

	static boolean compute(long slots){
		long[] na = a.clone();
		long A = na[2]/2;
		if (A >= slots)
			return (na[0] + na[1] >= slots);
		na[2] -= A * 2;
		slots -= A;
		long B = na[1] / 2;
		if (B < slots)
			return false;
		B = slots;
		na[1] -= slots * 2;
		//
		A -= na[1];
		if (A > 0){
			if (na[0] < A)
				return false;
			na[0] -= A;
			// A = 0
		}
		if (na[0] + na[2] >= B)
			return true;
		return false;
	}

	static boolean test(long s){
		return !compute(s);
	}

	public static void main(String args[]) throws NumberFormatException, IOException{
		Scanner sc = new Scanner();
		a = new long[3];
		for(int i = 0; i < 3; i++)
			a[i] = sc.nextInt();
		Arrays.sort(a);
		long low = 0;
		long high = 2000000000 + 10;
		while(low < high){
			long mid = (low + high)/2;
			//System.out.println(mid);
			if (test(mid))
				high = mid;
			else
				low = mid + 1;
		}
		System.out.println(Math.max(low - 1, Math.min(a[0], Math.min(a[1], a[2]))) );
	}

}

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

public class TableDecorations
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int[] a =
        { in.nextInt(), in.nextInt(), in.nextInt() };
        Arrays.sort(a);
        if (2 * (a[0] + a[1]) <= a[2])
            System.out.println(a[0] + a[1]);
        else
            System.out.println((a[0] + a[1] + a[2]) / 3);
        in.close();
    }
}

import java.util.*;

public class TableDecorations {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		Long[] rgb = new Long[3];
		rgb[0] = (long) sc.nextInt();
		rgb[1] = (long) sc.nextInt();
		rgb[2] = (long) sc.nextInt();
		Arrays.sort(rgb);
		if (rgb[2] > 2*(rgb[0] + rgb[1]) && rgb[0] + rgb[1] != 0)
			System.out.println(rgb[0] + rgb[1]);
		else
			System.out.println((rgb[0] + rgb[1] + rgb[2]) / 3);

	}

}

import java.util.Scanner;
public class sherif {
    public static void main (String args[]){
        Scanner sherif = new Scanner(System.in) ;
        long a ,b, c ;
        a = sherif.nextLong() ;
        b = sherif.nextLong();
        c = sherif.nextLong() ;
        System.out.print((a+b+c)/3);

    }

    private static long min(long a, long c) {
        if(a<c)return a ;
        return c;
    }

    private static long pow(int i, long count) {
        // TODO Auto-generated method stub
        return 0;
    }
}

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

public class C478 {

	public static void main(String[] args) throws NumberFormatException, IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] a = br.readLine().split(" ");
		int[] arr = new int[3];
		arr[0] = Integer.parseInt(a[0]);
		arr[1] = Integer.parseInt(a[1]);
		arr[2] = Integer.parseInt(a[2]);

		long ans = 0;
		if(2*arr[0] + 2*arr[1] <= arr[2])
			ans = arr[0] + arr[1];
		else ans = (arr[0] + arr[1] + arr[2])/3;
		System.out.println(ans);
	}
}

import java.util.*;
import java.io.*;
public class typo
{
    static  class InputReader {
        private InputStream stream;
        private byte[] inbuf = new byte[1024];
        private int start= 0;
        private int end = 0;

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

        private int readByte() {
            if (start == -1) throw new UnknownError();
            if (end >= start) {
                end= 0;
                try {
                    start= stream.read(inbuf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (start<= 0) return -1;
            }
            return inbuf[end++];
        }

        private boolean isSpaceChar(int c) {
            return !(c >= 33 && c <= 126);
        }

        private int skip() {
            int b;
            while ((b = readByte()) != -1 && isSpaceChar(b)) ;
            return b;
        }

        public String next() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while (!(isSpaceChar(b))) { // when nextLine, (isSpaceChar(b) && b != ' ')
                sb.appendCodePoint(b);
                b = readByte();
            }
            return sb.toString();
        }

        public int nextInt() {
            int num = 0, b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }

        public long nextLong() {
            long num = 0;
            int b;
            boolean minus = false;
            while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-')) ;
            if (b == '-') {
                minus = true;
                b = readByte();
            }

            while (true) {
                if (b >= '0' && b <= '9') {
                    num = num * 10 + (b - '0');
                } else {
                    return minus ? -num : num;
                }
                b = readByte();
            }
        }
    }
    public static void main(String args[])
    {
        InputReader sc=new InputReader(System.in);
        long n1=sc.nextLong();
        long n2=sc.nextLong();
        long n3=sc.nextLong();
        long a[]={n1,n2,n3};
        Arrays.sort(a);
        long ans=0;
        if(n1==0 || n2==0 || n3==0)
        {
            if(a[1]*2<=a[2])
            ans=a[1];
            else
            ans=(a[1]+a[2])/3;
        }
        else
        {
            ans=a[0];
            a[1]-=a[0];
            a[2]-=a[0];
           if(a[1]*2<=a[2])
            ans+=a[1];
            else
            ans+=(a[1]+a[2])/3;
        }
        System.out.println(ans);
    }
}

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

import static java.lang.Math.*;

public class Main {
    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        long a = nextInt();
        long b = nextInt();
        long c = nextInt();
        long f = min((a + b) / 2, c);
        long s = min((b + c) / 2, a);
        long t = min((a + c) / 2, b);
        long ans = max(f, max(s, t));
        pw.println(ans);
        pw.close();
    }

    static long mod = 1_000_000_007;

    static StringTokenizer st = new StringTokenizer("");
    static BufferedReader br;

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

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

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

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

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

public class Main {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int r = sc.nextInt(), g = sc.nextInt(), b = sc.nextInt();
        int min = Math.min(r, Math.min(g, b));
        int ans = min;
        r -= min;
        g -= min;
        b -= min;
        int max = Math.max(r, Math.max(g, b));
        int mid = getMid(r, g, b);
        while (max != 0 && mid != 0 && (max + mid > 2)) {
            int need = max / 2;
            if (mid <= need) {
                int swap = Math.min(need - mid, min);
                ans += swap + mid;
                mid = 0;
                max -= swap - mid;
            } else {
                max = max % 2;
                mid -= need;
                ans += need;
            }
            if (max < mid) {
                int tmp = max;
                max = mid;
                mid = tmp;
            }
        }
        out.println(ans);
        out.close();
        out.flush();

    }

    static int getMid(int a, int b, int c) {
        if (a >= b && a >= c) return b >= c ? b : c;
        if (b >= a && b >= c) return a >= c ? a : c;
        return a >= b ? a : b;
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public char nextChar() throws IOException {
            return next().charAt(0);
        }

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

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

        public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }

        public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public double[] nextDoubleArray(int n) throws IOException {
            double[] ans = new double[n];
            for (int i = 0; i < n; i++)
                ans[i] = nextDouble();
            return ans;
        }

        public short nextShort() throws IOException {
            return Short.parseShort(next());
        }

    }

}

/*
If you want to aim high, aim high
Don't let that studying and grades consume you
Just live life young
******************************
If I'm the sun, you're the moon
Because when I go up, you go down
*******************************
I'm working for the day I will surpass you
https://www.a2oj.com/Ladder16.html
*/
import java.util.*;
import java.io.*;
import java.math.*;

   public class x478C
   {
      public static void main(String omkar[]) throws Exception
      {
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int R = Integer.parseInt(st.nextToken());
         int G = Integer.parseInt(st.nextToken());
         int B = Integer.parseInt(st.nextToken());
         long[] arr = new long[3];
         arr[0] = R;
         arr[1] = G;
         arr[2] = B;
         Arrays.sort(arr);
         long res = R+G+B;
         if(R > 2*G+2*B)
            res -= R-2*G-2*B;
         else if(B > 2*R+2*G)
            res -= B-2*R-2*G;
         else if(G > 2*B+2*R)
            res -= G-2*B-2*R;
         res /= 3;
         System.out.println(res);
      }
   }

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main2 {

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        PrintWriter out;

        public FastReader(boolean fileInput) throws IOException {

            Reader reader = fileInput ? new FileReader("important.in") : new InputStreamReader(System.in);
            //Writer writer = fileIO ? new FileWriter("output.txt") : new OutputStreamWriter(System.out);
            Writer writer = new OutputStreamWriter(System.out);
            br = new BufferedReader(reader);
            out = new PrintWriter(new BufferedWriter(writer));
        }

        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;
        }
    }

    public static void main(String args[]) throws IOException {

        FastReader read = new FastReader(false);
        int r = read.nextInt();
        int g = read.nextInt();
        int b = read.nextInt();
        int[] arr = new int[3];
        arr[0] = r;
        arr[1] = g;
        arr[2] = b;
        Arrays.sort(arr);
        int ans = arr[0];
        arr[0] -= ans;
        arr[1] -= ans;
        arr[2] -= ans;
        int extra = -1;
        int oldExtra = extra;
        while(oldExtra != 0){
            extra = Math.min(arr[1],arr[2]/2);
            if(arr[1] < arr[2]){
                extra = Math.min(arr[1],arr[2]/2);
                arr[1] -= extra;
                arr[2] -= extra*2;
            }else { // arr[1] >= arr[2]
                arr[1] -= extra*2;
                arr[2] -= extra;
            }
            ans += extra;
            oldExtra = extra;
        }
        System.out.println(ans);

    }
}

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

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Ivan
 */
public class thirdProblem {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);
        long[] colors=new long[3];
        for(int i=0;i<3;i++)
            colors[i]=sc.nextLong();
        long tables=0;
        //System.out.println((colors[0]+colors[1]+colors[2])/3);
        Arrays.sort(colors);
        if(colors[2]/2>=colors[0]+colors[1])
            tables+=colors[0]+colors[1];
        else
        {
            if(colors[2]==colors[1]&&colors[2]!=1)
                tables+=colors[1]-1;
            else
                tables+=colors[1];
        }

        System.out.println(tables);

    }

}

class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

import java.util.*;
public class Main{
    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        int A[]=new int[3];
        int min = Integer.MAX_VALUE;
        for(int i=0;i<3;i++){
            A[i]=sc.nextInt();
            min = Math.min(min,A[i]);
        }
        for(int i=0;i<3;i++){
            A[i]-=min;
        }
        Arrays.sort(A);
        if(A[1]==0){
            System.out.println(min);
        }else{
            while(A[1]*2>A[2]){
                A[1]--;
            }
            min+=A[1];
            System.out.println(min);
        }

    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class CF273_C {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        String[] ss = s.split(" ");
        int r = Integer.parseInt(ss[0]);
        int g = Integer.parseInt(ss[1]);
        int b = Integer.parseInt(ss[2]);
        int[] list = new int[3];
        list[0] = r;
        list[1] = g;
        list[2] = b;
        Arrays.sort(list);
        int t = list[0];
        list[1] -= list[0];
        list[2] -= list[0];
        list[2] = Math.min(list[2], 2*list[1]);
        t += (list[1]+list[2])/3;
        System.out.println(t);
    }

}

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

public class Main {
    public static void main(String[] args) {
        MyScanner sc = new MyScanner();

        Integer[] arr = { sc.nextInt(), sc.nextInt(), sc .nextInt() };
        Arrays.sort(arr, Collections.reverseOrder());

        int dh02 = arr[0] - arr[2];
        int dh12 = arr[1] - arr[2];

        int count = 0;
        if (dh02 > 2 * dh12) {
            arr[0] -= 2 * dh12;
            arr[1] -= dh12;
            count += dh12;
        } else {
            int chng = dh02 / 2;
            arr[0] -= 2 * chng;
            arr[1] -= chng;
            count += chng;
        }

        Arrays.sort(arr, Collections.reverseOrder());
        if (arr[0] > 2 * (arr[1] + arr[2])) {
            System.out.println(count + arr[1] + arr[2]);
        } else {
            System.out.println(count + (arr[0] + arr[1] + arr[2]) / 3);
        }

        /*
        if (arr[2] > 2 * (arr[0] + arr[1])) {
            System.out.println(arr[0] + arr[1]);
        } else {

        }

        int min = arr[0];
        for (int i = 0; i < arr.length; i++)
            arr[i] -= min;

        int diff = Math.min(arr[1], arr[2] - arr[1]);
        arr[1] -= diff;
        arr[2] -= 2 * diff;

        int triples = Math.min(arr[1], arr[2]) / 3;
        arr[1] -= triples * 3;
        arr[2] -= triples * 3;

        int extra = 0;
        if ((arr[1] >= 1 && arr[2] >= 2) || (arr[2] >= 1 && arr[1] >= 2))
            extra = 1;

        int total = min + diff + 2 * triples + extra;
        System.out.println(total);
        */
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

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

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Ivan
 */
public class thirdProblem {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        Scanner sc=new Scanner(System.in);
        long[] colors=new long[3];
        for(int i=0;i<3;i++)
            colors[i]=sc.nextLong();
        long tables=0;
        //System.out.println((colors[0]+colors[1]+colors[2])/3);
        Arrays.sort(colors);
        if(colors[0]<=colors[2]/2)
        {
            tables=colors[0];
            colors[2]-=colors[0]*2;
            colors[0]=0;
        }
        else
        {
            tables+=colors[2]/2;
            colors[0]-=colors[2]/2;
            colors[2]-=colors[2]/2;

        }
        Arrays.sort(colors);
        if(colors[1]<=colors[2]/2)
        {
            tables+=colors[1];
            colors[2]-=colors[1]*2;
            colors[1]=0;

        }
        else
        {
            tables+=colors[2]/2;
            colors[1]-=colors[2]/2;
            colors[2]-=colors[2]/2;

        }

        Arrays.sort(colors);
        if(colors[0]+colors[1]+colors[2]==3&&colors[0]!=3&&colors[1]!=3&&colors[2]!=3)
            tables++;

        System.out.println(tables);

    }

}

class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;

    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }

    /** get next word */
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }

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

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

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

public class Rextester{
    public static void shuffle(int[] array){
        Random rand = new Random();
        for(int i=0;i<array.length;i++){
            int x = rand.nextInt(array.length-i)+i;
            int temp = array[x];
            array[x]=array[i];
            array[i]=temp;
        }
    }
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        br.close();
        int count=0;
        int[] array = new int[3];
        for(int i=0;i<3;i++){
            array[i]=new Integer(st.nextToken());
        }
        Arrays.sort(array);
        count+=array[0];
        array[1]-=array[0];
        array[2]-=array[0];
        while(array[2]>1&&array[1]>0){
            if(array[2]/2>array[1]){
                count+=array[1];
                array[2]-=2*array[1];
                array[1]-=array[1];
            }
            else{
                count+=array[2]/2;
                array[2]-=2*(array[2]/2);
                array[1]-=array[2]/2;
            }
            Arrays.sort(array);
        }
        System.out.println(count);
    }
}

import java.util.Scanner;
public class Main{
  public static void main(String[] args){
    Scanner sc = new Scanner(System.in);
    long a,b,d,e,f,c,j;
    a = sc.nextLong();
    b = sc.nextLong();
    c = sc.nextLong();
    d = a+b+c;
    j = Math.max(a,(Math.max(b,c)));
    b = Math.min(a,(Math.min(b,c)));
    c = d -j-b;
    //System.out.println(j+" "+b+" "+c);
    e = j-b;
    long i = 0;;
    f = c-b;
    //System.out.println(e+" "+f);
    while(f != 0 || e != 0){
      if(f> e){
        f = f-2;
        e = e-1;
      }else{
        e = e-2;
        f = f- 1;
      }
      if(e < 0|| f < 0 ){
        e = 0;
        f = 0;
        i--;
      }
      i++;
    }
    System.out.println(i+b);
  }
}

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

public class C {
    public static void solution(BufferedReader reader, PrintWriter out)
            throws IOException {
        In in = new In(reader);
        int[] c = new int[] { in.nextInt(), in.nextInt(), in.nextInt() };
        Arrays.sort(c);
        long cnt = 0;
        while (c[1] > c[0] && c[2] - c[0] > 1) {
            int t = Math.min(c[1] - c[0], (c[2] - c[0]) / 2);
            cnt += t;
            c[1] -= t;
            c[2] -= t + t;
            Arrays.sort(c);
        }
        System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
        if (c[1] - c[0] == 1 && c[2] - c[0] == 1) {
            cnt += c[0];
            System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
            out.println(cnt);
        }
        else {
            int t = Math.min(c[0], c[2] / 4);
            cnt += t + t;
            c[0] -= t;
            c[1] -= t;
            c[2] -= t * 4;
            Arrays.sort(c);
            System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
            cnt += c[0];
            c[1] -= c[0];
            c[2] -= c[0];
            c[0] = 0;
            System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
            cnt += c[1] / 3 * 2;
            c[1] %= 3;
            c[2] %= 3;
            System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
            if (c[1] == 2)
                cnt++;
            System.err.printf("%d %d %d => %d\n", c[0], c[1], c[2], cnt);
            out.println(cnt);
        }
    }

    public static void main(String[] args) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                System.in));
        PrintWriter out = new PrintWriter(new BufferedWriter(
                new OutputStreamWriter(System.out)));
        solution(reader, out);
        out.close();
    }

    protected static class In {
        private BufferedReader reader;
        private StringTokenizer tokenizer = new StringTokenizer("");

        public In(BufferedReader reader) {
            this.reader = reader;
        }

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

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

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

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

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

public class TableDeorations {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner scn=new Scanner(System.in);
		long []a=new long[3];
		a[0]=scn.nextLong();
		a[1]=scn.nextLong();
		a[2]=scn.nextLong();
		Arrays.sort(a);
		long sum=a[0];
		a[0]=0;
		a[1]-=sum;
		a[2]-=sum;
		//System.out.println(a[1]+" "+a[2]);
		if(a[2]>=a[1]*2l&&a[1]!=0) {
			//long x=Math.min(a[1], a[2]);
			a[2]-=a[1];
			sum+=a[1];
			//System.out.println(sum+" "+a[2]/3l);
			if(a[2]/3>a[1])
			sum+=a[1];
			else {
				sum+=a[2]/3l;
			}

			//System.out.println(sum+" aaaaa");
		}else {
			sum+=(a[2]+a[1])/3l;
			//System.out.println("kkk");
		}
		System.out.println(sum);
	}

}

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

public class CF478C implements Runnable {

    public void run() {
        int[] c = new int[3];
        for (int i = 0; i < 3; ++i) {
            c[i] = nextInt();
        }
        Arrays.sort(c);
        int ans = c[0];
        c[1] -= c[0];
        c[2] -= c[0];

        int add = Math.min(c[1], c[2]/2);
        while(add > 0) {
            c[1] -= add;
            c[2] -= add*2;
            ans += add;
            Arrays.sort(c);
            add = Math.min(c[1], c[2]/2);
        }

        out.println(ans);
        out.flush();
    }

    private static BufferedReader br = null;
    private static PrintWriter out = null;
    private static StringTokenizer stk = null;
    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        (new CF478C()).run();
    }

    private void loadLine() {
        try {
            stk = new StringTokenizer(br.readLine());
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String nextLine() {
        try {
            return (br.readLine());
        }
        catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private int nextInt() {
        while (stk == null || !stk.hasMoreElements()) loadLine();
        return Integer.parseInt(stk.nextToken());
    }

    private long nextLong() {
        while (stk == null || !stk.hasMoreElements()) loadLine();
        return Long.parseLong(stk.nextToken());
    }

    private double nextDouble() {
        while (stk == null || !stk.hasMoreElements()) loadLine();
        return Double.parseDouble(stk.nextToken());
    }

    private String nextWord() {
        while (stk == null || !stk.hasMoreElements()) loadLine();
        return (stk.nextToken());
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        CTableDecorations solver = new CTableDecorations();
        solver.solve(1, in, out);
        out.close();
    }

    static class CTableDecorations {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int ntc = 1;
//        ntc = in.nextInt();
            while ((ntc--) > 0) {
                int r = in.nextInt();
                int g = in.nextInt();
                int b = in.nextInt();
                long ans = 0;
                ans = _F.min(r, g, b);
                r -= ans;
                g -= ans;
                b -= ans;
                int[] arr = new int[]{r, g, b};
                Arrays.sort(arr);
                if (arr[1] != 0) {
                    ans += (_F.min(arr[1], (arr[1] + arr[2]) / 3));
                }
                out.println(ans);
            }
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void close() {
            writer.close();
        }

        public void println(long i) {
            writer.println(i);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(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++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }

    static class _F {
        public static <T extends Comparable<T>> T min(T... list) {
            T candidate = list[0];
            for (T i : list) {
                if (candidate.compareTo(i) > 0) {
                    candidate = i;
                }
            }
            return candidate;
        }

    }
}

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.TreeMap;

public class D {
	public static long[] dp;
	public static TreeMap<Integer, Integer> map;

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		InputReader s = new InputReader(System.in);
		PrintWriter p = new PrintWriter(System.out);
		int[] arr = new int[3];
		arr[0] = s.nextInt();
		arr[1] = s.nextInt();
		arr[2] = s.nextInt();
		int ans = 0;
		Arrays.sort(arr);
		int diff = arr[2] - arr[1];
		if (arr[1] - diff >= arr[0]) { // b=c
			ans += diff;
			arr[1] -= diff;
			arr[2] -= 2 * diff;
			diff = arr[1] - arr[0];
			ans += 2 * (diff) / 3;
			arr[1] -= (3 * (diff / 3));
			arr[2] -= (3 * (diff / 3));
			ans += arr[0];
			arr[1] -= arr[0];
			arr[2] -= arr[0];
			if (arr[1] == 1 && arr[2] >= 2) {
				ans++;
			}
			System.out.println(ans);
			return;
		} else { // a=b
			diff = arr[1] - arr[0];
			ans += diff;
			arr[1] -= diff;
			arr[2] -= 2 * diff;
			if (arr[2] >= 4 * arr[0]) {
				ans += 2 * arr[0];
				arr[1] -= arr[0];
				arr[2] -= 4 * arr[0];
				if (arr[2] >= 2 && arr[1] == 1)
					ans++;
				System.out.println(ans);
				return;
			} else {
				int a = arr[0];
				int b = arr[1];
				int c = arr[2];
				ans += 2 * (c - a) / 3;
				a -= (c - a) / 3;
				b -= (c - a) / 3;
				c -= (c - a) / 3 * 4;
				ans += a;
				b -= a;
				c -= a;
				if(b >= 1 && c>=2)
					ans++;
				System.out.println(ans);
			}
		}
		p.flush();
		p.close();
	}

	public static long getmax(int i) {
		if (i > map.lastKey()) {
			return 0;
		}
		if (!map.containsKey(i)) {
			long ans = getmax(i + 1);
			dp[i] = ans;
			return ans;
		}
		long ans1 = i * map.get(i) + getmax(i + 2);
		long ans2 = getmax(i + 1);
		long ans = Math.max(ans1, ans2);
		dp[i] = ans;
		return ans;
	}

	static class pair implements Comparable<pair> {
		Long x, y;

		pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		public int compareTo(pair o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);

			return result;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Object o) {
			if (o instanceof pair) {
				pair p = (pair) o;
				return p.x - x == 0 && p.y - y == 0;
			}
			return false;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
		}
	}

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

	public static ArrayList<Long> Divisors(long n) {
		ArrayList<Long> div = new ArrayList<>();

		for (long i = 1; i <= Math.sqrt(n); i++) {
			if (n % i == 0) {
				div.add(i);
				if (n / i != i)
					div.add(n / i);
			}
		}
		return div;
	}

	public static int BinarySearch(long[] a, long k) {
		int n = a.length;
		int i = 0, j = n - 1;
		int mid = 0;

		if (k < a[0])
			return 0;
		else if (k >= a[n - 1])
			return n;
		else {
			while (j - i > 1) {
				mid = (i + j) / 2;

				if (k >= a[mid])
					i = mid;
				else
					j = mid;
			}
		}

		return i + 1;
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static long LCM(long a, long b) {
		return (a * b) / GCD(a, b);
	}

//	static class pair implements Comparable<pair> {
//		Integer x, y;
//
//		pair(int x, int y) {
//			this.x = x;
//			this.y = y;
//		}
//
//		public int compareTo(pair o) {
//			int result = x.compareTo(o.x);
//			if (result == 0)
//				result = y.compareTo(o.y);
//
//			return result;
//		}
//
//		public String toString() {
//			return x + " " + y;
//		}
//
//		public boolean equals(Object o) {
//			if (o instanceof pair) {
//				pair p = (pair) o;
//				return p.x - x == 0 && p.y - y == 0;
//			}
//			return false;
//		}
//
//		public int hashCode() {
//			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
//		}
//	}

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

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

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

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

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

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}

	static class CodeX {
		public static void sort(long arr[]) {
			merge_sort(arr, 0, arr.length - 1);
		}

		private static void merge_sort(long A[], long start, long end) {
			if (start < end) {
				long mid = (start + end) / 2;
				merge_sort(A, start, mid);
				merge_sort(A, mid + 1, end);
				merge(A, start, mid, end);
			}

		}

		private static void merge(long A[], long start, long mid, long end) {
			long p = start, q = mid + 1;
			long Arr[] = new long[(int) (end - start + 1)];
			long k = 0;

			for (int i = (int) start; i <= end; i++) {
				if (p > mid)
					Arr[(int) k++] = A[(int) q++];

				else if (q > end)
					Arr[(int) k++] = A[(int) p++];

				else if (A[(int) p] < A[(int) q])
					Arr[(int) k++] = A[(int) p++];

				else
					Arr[(int) k++] = A[(int) q++];
			}
			for (int i = 0; i < k; i++) {
				A[(int) start++] = Arr[i];
			}

		}

	}

}

import java.util.Scanner;

public class C478 {
	static int INF = (int)2e9;
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int r = sc.nextInt(), g = sc.nextInt(), b = sc.nextInt();

		if((r==g&b>=r)|(r==b&g>=r)|(g==b&r>=g))
			System.out.println(r==g|r==b?r:g);
		else
		{
			int ans = Math.min(r, Math.min(g, b));
			r -= ans; g -= ans; b -= ans;

			if(r+g+b>=3)
			{
				if(r==g|r==b|g==b)
					ans += (Math.max(r, g)*2)/3;
				else
				{
					int sub = Math.min(r!=0?r:INF, Math.min(g!=0?g:INF, b!=0?b:INF))/3;
					ans += sub*2;

					r -= sub*3; g -= sub*3; b -= sub*3;
					r = Math.max(r, 0); g = Math.max(g, 0); b = Math.max(b, 0);

					if(r==0)
						ans += Math.min(Math.max(g, b)/2,Math.min(g, b));
					else if(g==0)
						ans += Math.min(Math.max(r, b)/2,Math.min(r, b));
					else
						ans += Math.min(Math.max(r, g)/2,Math.min(r, g));
				}
			}

			System.out.println(ans);
		}
	}

}

// 478C - Table Decorations
import java.util.Arrays;
import java.util.Scanner;

public class tabledecorations {

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

		int[] c = new int[3];
		c[0] = in.nextInt();
		c[1] = in.nextInt();
		c[2] = in.nextInt();

		int tables = 0;
		Arrays.sort(c);
		if(c[2] > 1){
			int change = Math.min(c[2]/2, c[1]);
			c[2] -= change*2;
			c[1] -= change;
			tables += change;
		}

		Arrays.sort(c);
		if(c[2] > 1){
			int change = Math.min(c[2]/2, c[1]);
			c[2] -= change*2;
			c[1] -= change;
			tables += change;
		}

		Arrays.sort(c);
		if(c[2] > 1){
			int change = Math.min(c[2]/2, c[1]);
			c[2] -= change*2;
			c[1] -= change;
			tables += change;
		}

		Arrays.sort(c);

		if(c[0] == 0){
			System.out.println(tables);
			return;
		}

		System.out.println(tables+1);

	}

}

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

public class TableDecorations {
    public static void main(String[]args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String [] in = br.readLine().split(" ");
        long r = Long.parseLong(in[0]);
        long g = Long.parseLong(in[1]);
        long b = Long.parseLong(in[2]);
        if (r == 0 && g == 0 || r == 0 && b == 0 || g == 0 && b == 0) {
            System.out.println(0);
            return;
        }
        System.out.println((r+g+b)/3);
    }

    /*
    public static int solve(int r, int g, int b) {
        if (r == g && g == b && r == 1) {
            return 1;
        }

        if (r == 0 && g == 0 || r == 0 && b == 0 || b == 0 && g == 0) {
            return 0;
        }

        int i = 0;
        int j = 0;
        int k = 0;
        int l = 0;
        int m = 0;
        int w = 0;
        int x = 0;
        if (r > 0 && g > 0 && b > 0)
            i = 1+solve(r-1, g-1, b-1);
        if (r > 0 && g > 1)
            j = 1+solve(r-1, g-2, b);
        if (r > 0 && b > 1)
            k = 1+solve(r-1, g, b-2);
        if (g > 0 && b > 1)
            l = 1+solve(r, g-1, b-2);
        if (g > 1 && b > 0)
            m = 1+solve(r, g-2, b-1);
        if (r > 1 && g > 0)
            w = 1+solve(r-2, g-1, b);
        if (r > 2 && b > 0)
            x = 1+solve(r-2, g, b-1);
        return Math.max(i, Math.max(j, Math.max(k, Math.max(l, Math.max(m, Math.max(w, x))))));
        }*/
}

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

public class Program {

    private static PrintWriter out;

    private static <T> void mprintln(T ... ar){
        for(T i: ar) out.print(i + " ");
        out.println();
    }

    public static void main(String[] args) throws FileNotFoundException{

        // Input from file
        // File inputFile = new File("JavaFile.txt");
        // File outputFile = new File("JavaOutputFile.txt");
        // FileReader fileReader = new FileReader(inputFile);
        // Here it ends

        MyScanner sc = new MyScanner();
        // MyScanner sc = new MyScanner(fileReader);

        out = new PrintWriter(new BufferedOutputStream(System.out)); // Output to console
        // out = new PrintWriter(new PrintStream(outputFile)); // Output to file

        getAns(sc);

        out.close();
    }

    private static void getAns(MyScanner sc){
        long[] ar = sc.nlArr0(3);
        Arrays.sort(ar);

        long ans = (ar[2] - ar[1]) / 2;
        ans = Math.min(ar[0], ans);
        ar[0] -= ans;
        ar[2] -= 2 * ans;

        ar[1] -= ar[0];
        ar[2] -= ar[0];
        ans += ar[0];
        ar[0] = 0;

        if(ar[1] + ar[2] < 3){
            out.println(ans);
            return;
        }

//        out.println(Arrays.toString(ar));

        long diff = ar[2] - ar[1];
        ans += diff;
        ar[1] -= diff;
        ar[2] -= 2 * diff;

        ans += ar[1] / 3 * 2;
        ar[1] %= 3;

        if(ar[1] == 2) ++ans;

        out.println(ans);

    }

    static class MyScanner{
        BufferedReader br;
	StringTokenizer st;

	MyScanner(FileReader fileReader){
            br = new BufferedReader(fileReader);
	}

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

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

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

	char nc(){
            return nn().charAt(0);
	}

	int ni(){
            return Integer.parseInt(nn());
	}

	long nl(){
            return Long.parseLong(nn());
	}

	double nd(){
            return Double.parseDouble(nn());
	}

	int[] niArr0(int n){
            int[] ar = new int[n];
            for(int i = 0; i < n; i++) ar[i] = ni();
            return ar;
	}

        int[] niArr1(int n){
            int[] ar = new int[n + 1];
            for(int i = 1; i <= n; i++) ar[i] = ni();
            return ar;
	}

        long[] nlArr0(int n){
            long[] ar = new long[n];
            for(int i = 0; i < n; i++) ar[i] = nl();
            return ar;
        }

        long[] nlArr1(int n){
            long[] ar = new long[n + 1];
            for(int i = 1; i <= n; i++) ar[i] = nl();
            return ar;
        }
    }
}

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

public class Main478C2

{
  static PrintWriter out=new PrintWriter(System.out);

  public static void main(String[] args) throws IOException
  {
    Scanner sc=new Scanner(System.in);
    int r=sc.nextInt();
    int g=sc.nextInt();
    int b=sc.nextInt();
    long ans=((long)r+g+b);
    int min=Math.min(r,Math.min(g,b));
    int max=Math.max(r,Math.min(g,b));
    long h=ans-min-max;
    ans=Math.min(ans/3,h);
    out.println(ans);
    out.flush();

  }
  static class Scanner
  {
    BufferedReader br;
    StringTokenizer tk=new StringTokenizer("");
    public Scanner(InputStream is)
        {
      br=new BufferedReader(new InputStreamReader(is));
    }
        public int nextInt() throws IOException
        {
          if(tk.hasMoreTokens())
                return Integer.parseInt(tk.nextToken());
          tk=new StringTokenizer(br.readLine());
          return nextInt();
        }
        public long nextLong() throws IOException
        {
            if(tk.hasMoreTokens())
              return Long.parseLong(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextLong();
        }
        public String next() throws IOException
        {
          if(tk.hasMoreTokens())
            return (tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return next();
        }
        public String nextLine() throws IOException
        {
          tk=new StringTokenizer("");
          return br.readLine();
        }
        public double nextDouble() throws IOException
        {
            if(tk.hasMoreTokens())
              return Double.parseDouble(tk.nextToken());
            tk=new StringTokenizer(br.readLine());
            return nextDouble();
        }
        public char nextChar() throws IOException
        {
            if(tk.hasMoreTokens())
              return (tk.nextToken().charAt(0));
            tk=new StringTokenizer(br.readLine());
            return nextChar();
        }
        public int[] nextIntArray(int n) throws IOException
        {
            int a[]=new int[n];
            for(int i=0;i<n;i++)
              a[i]=nextInt();
            return a;
        }
        public long[] nextLongArray(int n) throws IOException
        {
          long a[]=new long[n];
            for(int i=0;i<n;i++)
              a[i]=nextLong();
            return a;
        }
        public int[] nextIntArrayOneBased(int n) throws IOException
        {
          int a[]=new int[n+1];
            for(int i=1;i<=n;i++)
              a[i]=nextInt();
            return a;
        }
        public long[] nextLongArrayOneBased(int n) throws IOException
        {
          long a[]=new long[n+1];
          for(int i=1;i<=n;i++)
                a[i]=nextLong();
          return a;
        }
  }
}

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

public class TableDecorations {
    public static void main(String[] args)throws IOException {
        BufferedReader inp = new BufferedReader(new InputStreamReader(System.in));
        String[] s1 = inp.readLine().split(" ");

        int[] balls = new int[3];

        balls[0] = Integer.parseInt(s1[0]);
        balls[1] = Integer.parseInt(s1[1]);
        balls[2] = Integer.parseInt(s1[2]);
        int ans = 0;
        Arrays.sort(balls);
        while(balls[1]>=1 && balls[2]>=2){

            balls[2] = balls[2]-2;
            balls[1] = balls[1]-1;
            Arrays.sort(balls);
            //System.out.println(balls[0]+" "+balls[1]+" "+balls[2]+" ");
            ans++;
        }
        if(balls[0]>0&&balls[1]>0&&balls[2]>1){
            ans++;
        }

        System.out.println(ans);
    }
}

import java.io.*;
import java.util.*;
public class Main {

    public static void main(String[] args)
    {
        InputStream inputstream = System.in;
        OutputStream outputstream = System.out;
        InputReader in = new InputReader(inputstream);
        OutputWriter out = new OutputWriter(outputstream);
        mysolver mysol = new mysolver();
        mysol.solve(in, out);
        out.close();
    }

}

class mysolver {
    public void solve(InputReader in,OutputWriter out)
    {
    	PrintWriter pout = new PrintWriter(new BufferedOutputStream(System.out));
    	long A[] = new long[3];
    	for(int i=0;i<3;i++)
    		A[i] = in.readInt();
    	long ans = 0;
    	Arrays.sort(A);
    	ans = ans + A[0];
    	A[1] -= A[0];
    	A[2] -= A[0];
    	A[0] = 0;
    	Arrays.sort(A);
    	while(A[1]!=0)
    	{
    		if(A[1]== 1 && A[2] == 1)
    			break;
    		long val1 = A[2];
    		long val2 = A[1];

    		if(A[1]== A[2]&& A[1]==2)
    		{
    			ans = ans + 1;
    			break;
    		}
    		if(A[1]==A[2])
    		{
    			ans = ans + (val1/3)*2;
    			A[2] = A[2] - (val1/3)*3;
    			A[1] = A[1] - (val1/3)*3;

    		}
    		else if(A[1]-(A[2]-A[1])<0)
    		{
    			val1 = val1 - 2*A[1];
    			val2 = val2 - A[1];
    			ans = ans + A[2]-A[1];
    			A[2] = val1;
    			A[1] = val2;

    		}
    		else
    		{
    			val1 = val1 - 2*(A[2]-A[1]);
    			val2 = val2 - (A[2]-A[1]);
    			ans = ans + A[1];
    			A[2] = val1;
    			A[1] = val2;

    		}
    		Arrays.sort(A);
    	}
    	pout.println(ans);
    	pout.close();
    }

}
class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(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++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void close() {
        writer.close();
    }

    public void printLine(int i) {
        writer.println(i);
    }
}

class IOUtils {

    public static void readIntArrays(InputReader in, int[]... arrays) {
        for (int i = 0; i < arrays[0].length; i++) {
            for (int j = 0; j < arrays.length; j++)
                arrays[j][i] = in.readInt();
        }
    }

    }

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

public class TableDecorations
{
    public static void main(String[] args)
    {
        Scanner in = new Scanner(System.in);
        int r = in.nextInt(), g = in.nextInt(), b = in.nextInt();
        int m = Math.min(r, Math.min(g, b));
        int[] a =
        { r - m, b - m, g - m };
        Arrays.sort(a);
        int x = a[1], y = a[2];
        if (x >= 1 && y >= 2 && x * 2 <= y)
            m += x;
        else if(x == y && x + y >= 3)
            m += (int)Math.ceil(y / 2);
        System.out.println(m);
        in.close();
    }
}

import java.util.Scanner;
public class TableDecorations {

    public static void main(String[] args) {
        Scanner input= new Scanner(System.in);
        long r, b, g, s=0, c=0;
        r=input.nextInt();
        b=input.nextInt();
        g=input.nextInt();
        s=b+g+r;
        s/=3;
        if(c==0)
        {
        if(r>=b)
            if(r>=g)
                r=0;
        else
                if(b>=g)
                    b=0;
                else
                    g=0;
        }
        if(s> (b+g+r))
            System.out.println(b+g+r);
        else
            System.out.println(s);
    }
}

import java.util.Scanner;

/**
 * Created by msi on 3/30/2017.
 */
public class TableDecorations {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int r = in.nextInt();
        int g = in.nextInt();
        int b = in.nextInt();

        long a1, a2, a3;
        a1 = Math.max(Math.max(r, g), b);
        a3 = Math.min(Math.min(r, g), b);
        a2 = r - a1 + g - a3 + b;

        long tables = 0;
        while ((a1 > 1 && a2 > 0) || (a1 > 0 && a2 > 0 && a3 > 0)) {
            //a1 , a2 , a3 decresing
            if (a1 == a2 && a2 == a3 && a1 > 0) {
                tables += a1;
                a1 = 0;
                a2 = 0;
                a3 = 0;
                break;
            } else {
                while (a1 >= a2 && a2 >= a3) {
                    a1 -= 2;
                    a2 -= 1;
                    tables++;
                }
            }
            long b1, b2, b3;
            b1 = Math.max(Math.max(a1, a2), a3);
            b3 = Math.min(Math.min(a1, a2), a3);
            b2 = a1 - b1 + a2 - b3 + a3;
            a1 = b1;
            a2 = b2;
            a3 = b3;
            //    System.out.println(a1 + " " + a2 + " " + a3);
        }

        System.out.println(tables);
    }

}

import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author AlexFetisov
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int a = in.nextInt();
        int b = in.nextInt();
        int c = in.nextInt();
        long res = Math.min(a, Math.min(b, c));
        a -= res;
        b -= res;
        c -= res;

        if (a == 0) {
            int t = a;
            a = c;
            c = t;
        }
        if (b == 0) {
            int t = b;
            b = c;
            c = t;
        }

        if (a < b) {
            int t = a;
            a = b;
            b = t;
        }
        res += Math.min(a / 2, b);
        out.println(res);
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer stt;

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

    public String nextLine() {
        try {
            return reader.readLine().trim();
        } catch (IOException e) {
            return null;
        }
    }

    public String nextString() {
        while (stt == null || !stt.hasMoreTokens()) {
            stt = new StringTokenizer(nextLine());
        }
        return stt.nextToken();
    }

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

}

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

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

	void solve()
	{
		int a[] = na(3);
		Arrays.sort(a);

		if(2*(a[0]+a[1])<=a[2]) out.println(a[0]+a[1]);
		else out.println((a[0]+a[1]+a[2])/3);
	}

	void run() throws Exception
	{
		is = INPUT.isEmpty() ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

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

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

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private static void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}

import java.util.*;

import org.omg.CORBA.INTERNAL;

import java.awt.List;
import java.io.*;
import java.lang.*;
import java.lang.reflect.Array;

public class code3 {

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		// Code starts..

		long r = in.nextLong();
		long g = in.nextLong();
		long b = in.nextLong();

		long min = Math.min(r, Math.min(g, b));
		r -= min;
		g -= min;
		b -= min;
		long[] a = new long[3];
		a[0] = r;
		a[1] = g;
		a[2] = b;
		long ans = min;
		long n = -1;
		long m = -1;
		Arrays.sort(a);
		n = a[1];
		m = a[2];

		while(m+n>=3 && m!=0 && n!=0)
		{
			if(m<n)
			{
				long tmp = n;
				n = m;
				m = tmp;
			}

				if(2*n > m )
				{
					ans += m/2;
					n -= m/2;
					m -= 2*(m/2);
				}
				else
				{

					ans += n;
					m -= 2*n;;
					n = 0;
				}
			//	pw.println(n +" "+m+" "+ans);

		}
		if(m+n>=3)
		{
			if(m==0)
				m = n;

			ans += Math.min(m/3, min);
		}

		pw.println(ans);

		// code ends...

		pw.flush();
		pw.close();
	}

	public static double pow(double x, int n)
	{

		double ans = 1;
		for(int i=0; i<n; i++)
			ans *= x;
		return ans;
	}

	public static boolean check(String s1, String s2){

		boolean status = true;

        if(s1.length() != s2.length())
        {
            status = false;
        }
        else {
            char[] s1Array = s1.toLowerCase().toCharArray();

            char[] s2Array = s2.toLowerCase().toCharArray();
            Arrays.sort(s1Array);
            Arrays.sort(s2Array);
            status = Arrays.equals(s1Array, s2Array);
        }
        if(status)
        	return true;

        	return false;
    }

	public static long[][] mul(long[][] a, long[][] b){

		int n = a.length;
		int m = b[0].length;
		long[][] c = new long[n][m];

		for(int i=0; i<n; i++)
			for(int j=0; j<m; j++)
			{
				long tmp = 0;
				for(int k=0; k<a[0].length; k++)
					tmp =( (tmp+mod)%mod+(a[i][k]*b[k][j]+mod)%mod)%mod;
				c[i][j] = (tmp+mod)%mod;
			}

		return c;
	}

	public static long[][] pow(long[][] a,int  n)
	{

		long[][] res = a;
		while(n>0)
		{
			if(n%2==1)
			{
				res = mul(a, res);
			}

			a = mul(a, a);

			n/=2;

		}

		return res;

	}

	public static boolean isSubSequence(char[] str2, String str1) {

		int j = 0;
		int m = str1.length();
		int n = str2.length;

		for (int i = 0; i < n && j < m; i++)

			if (str1.charAt(j) == str2[i])

				j++;

		return (j == m);
	}

	static class InputReader {

		private final InputStream stream;
		private final byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;

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

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

		public int nextInt() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

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

		public String readString() {
			int c = snext();
			while (isSpaceChar(c)) {
				c = snext();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public String nextLine() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}

	public static long c = 0;

	public static long mod = (long)Math.pow(10, 6)+3;
	public static int d;
	public static int p;
	public static int q;
	public static boolean flag;
	//public static long INF = Long.MAX_VALUE;

	public static void factSieve(int[] fact, long n) {

		for (int i = 2; i <= n; i += 2)
			fact[i] = 2;

		for (int i = 3; i <= n; i += 2) {
			if (fact[i] == 0) {
				fact[i] = i;

				for (int j = i; (long) j * i <= n; j++) {
					fact[(int) ((long) i * j)] = i;
				}
			}
		}

		/*
		 * int k = 1000; while(k!=1) { System.out.print(a[k]+" "); k /= a[k];
		 *
		 * }
		 */
	}

	public static long floorsqrt(long n) {
		long ans = 0;
		long l = 0;
		long r = n;
		long mid = 0;
		while (l <= r) {
			mid = (l + r) / 2;
			if (mid * mid == n)
				return mid;

			if (mid * mid > n) {
				r = mid - 1;
			} else {
				ans = mid;
				l = mid + 1;
			}

		}

		return ans;
	}

	public static long fun(int[] a, int[] b, int m, int n) {
		long result = 0;
		for (int i = 0; i < m; i++)
			for (int j = 0; j < m; j++) {
				long[] fib = new long[Math.max(2, n + 2)];
				fib[1] = a[i];
				fib[2] = b[j];
				for (int k = 3; k <= n; k++)
					fib[k] = (fib[k - 1] % mod + fib[k - 2] % mod) % mod;
				result = (result % mod + fib[n] % mod) % mod;
			}

		return result;

	}

	/*
	 * public static double slope(pair p1, pair p2) { double m = INF; if((p1.x -
	 * p2.x)!=0) m = p1.y - p2.y/(p1.x - p2.x);
	 *
	 *
	 * return Math.abs(m);
	 *
	 * }
	 */

	public static int gcd(int p2, int p22) {
		if (p2 == 0)
			return (int) p22;
		return gcd(p22 % p2, p2);
	}

	public static int findGCD(int arr[], int n) {
		int result = arr[0];
		for (int i = 1; i < n; i++)
			result = gcd(arr[i], result);

		return result;
	}

	public static void nextGreater(long[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] < a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] >= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static void nextGreaterRev(long[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] < arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] >= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmallerRev(int[] a, int[] ans) {

		int n = a.length;
		int[] pans = new int[n];
		Arrays.fill(pans, -1);
		long[] arev = new long[n];
		for (int i = 0; i < n; i++)
			arev[i] = a[n - 1 - i];

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < n; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (arev[s] > arev[i]) {
					pans[s] = n - i - 1;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (arev[s] <= arev[i])
					stk.push(s);
			}

			stk.push(i);

		}

		// for(int i=0; i<n; i++)
		// System.out.print(pans[i]+" ");

		for (int i = 0; i < n; i++)
			ans[i] = pans[n - i - 1];

		return;

	}

	public static void nextSmaller(int[] a, int[] ans) {

		Stack<Integer> stk = new Stack<>();
		stk.push(0);

		for (int i = 1; i < a.length; i++) {

			if (!stk.isEmpty()) {
				int s = stk.pop();
				while (a[s] > a[i]) {
					ans[s] = i;
					if (!stk.isEmpty())
						s = stk.pop();
					else
						break;
				}
				if (a[s] <= a[i])
					stk.push(s);
			}

			stk.push(i);

		}
		return;

	}

	public static long lcm(int[] numbers) {
		long lcm = 1;
		int divisor = 2;
		while (true) {
			int cnt = 0;
			boolean divisible = false;
			for (int i = 0; i < numbers.length; i++) {
				if (numbers[i] == 0) {
					return 0;
				} else if (numbers[i] < 0) {
					numbers[i] = numbers[i] * (-1);
				}
				if (numbers[i] == 1) {
					cnt++;
				}
				if (numbers[i] % divisor == 0) {
					divisible = true;
					numbers[i] = numbers[i] / divisor;
				}
			}
			if (divisible) {
				lcm = lcm * divisor;
			} else {
				divisor++;
			}
			if (cnt == numbers.length) {
				return lcm;
			}
		}
	}

	public static long fact(long n) {

		long factorial = 1;
		for (int i = 1; i <= n; i++) {
			factorial *= i;
		}
		return factorial;
	}

	public static int lowerLimit(int[] a, int n) {
		int ans = 0;

		int ll = 0;
		int rl = a.length - 1;
		// System.out.println(a[rl]+" "+n);
		if (a[0] > n)
			return 0;
		if (a[0] == n)
			return 1;
		else if (a[rl] <= n)
			return rl + 1;

		while (ll <= rl) {

			int mid = (ll + rl) / 2;
			if (a[mid] == n) {
				ans = mid + 1;
				break;
			}

			else if (a[mid] > n) {
				rl = mid - 1;

			} else {
				ans = mid + 1;
				ll = mid + 1;
			}
		}

		return ans;
	}

	public static long choose(long total, long choose) {
		if (total < choose)
			return 0;
		if (choose == 0 || choose == total)
			return 1;
		return (choose(total - 1, choose - 1) + choose(total - 1, choose)) % mod;
	}

	public static int[] suffle(int[] a, Random gen) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}
		return a;
	}

	public static int floorSearch(int arr[], int low, int high, int x) {
		if (low > high)
			return -1;

		if (x > arr[high])
			return high;
		int mid = (low + high) / 2;

		if (mid > 0 && arr[mid - 1] < x && x < arr[mid])
			return mid - 1;

		if (x < arr[mid])
			return floorSearch(arr, low, mid - 1, x);

		return floorSearch(arr, mid + 1, high, x);
	}

	public static void swap(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
	}

	public static ArrayList<Integer> primeFactorization(int n) {
		ArrayList<Integer> a = new ArrayList<Integer>();
		for (int i = 2; i * i <= n; i++) {
			while (n % i == 0) {
				a.add(i);
				n /= i;
			}
		}
		if (n != 1)
			a.add(n);
		return a;
	}

	public static void sieve(boolean[] isPrime, int n) {
		for (int i = 1; i < n; i++)
			isPrime[i] = true;

		isPrime[0] = false;
		isPrime[1] = false;

		for (int i = 2; i * i < n; i++) {
			if (isPrime[i] == true) {
				for (int j = (2 * i); j < n; j += i)
					isPrime[j] = false;
			}
		}
	}

	public static int lowerbound(ArrayList<Long> net, long c2) {
		int i = Collections.binarySearch(net, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int lowerboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 2);
		return i;

	}

	public static int uperbound(ArrayList<Integer> list, int c2) {
		int i = Collections.binarySearch(list, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static int uperboundArray(int[] dis, int c2) {
		int i = Arrays.binarySearch(dis, c2);
		if (i < 0)
			i = -(i + 1);
		return i;

	}

	public static long[] sort(long[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			long temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int[] sort(int[] a) {
		Random gen = new Random();
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int ind = gen.nextInt(n - i) + i;
			int temp = a[ind];
			a[ind] = a[i];
			a[i] = temp;
		}

		Arrays.sort(a);
		return a;
	}

	public static int GCD(int a, int b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static long GCD(long a, long b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	public static void extendedEuclid(int A, int B) {
		if (B == 0) {
			d = A;
			p = 1;
			q = 0;
		} else {
			extendedEuclid(B, A % B);
			int temp = p;
			p = q;
			q = temp - (A / B) * q;
		}
	}

	public static long LCM(long a, long b) {
		return (a * b) / GCD(a, b);
	}

	public static int LCM(int a, int b) {
		return (a * b) / GCD(a, b);
	}

	public static int binaryExponentiation(int x, int n) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = x * x;
			n = n / 2;
		}
		return result;
	}

	public static int[] countDer(int n) {
		int der[] = new int[n + 1];

		der[0] = 1;
		der[1] = 0;
		der[2] = 1;

		for (int i = 3; i <= n; ++i)
			der[i] = (i - 1) * (der[i - 1] + der[i - 2]);

		// Return result for n
		return der;
	}

	static long binomialCoeff(int n, int k) {
		long C[][] = new long[n + 1][k + 1];
		int i, j;

		// Calculate value of Binomial Coefficient in bottom up manner
		for (i = 0; i <= n; i++) {
			for (j = 0; j <= Math.min(i, k); j++) {
				// Base Cases
				if (j == 0 || j == i)
					C[i][j] = 1;

				// Calculate value using previosly stored values
				else
					C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
			}
		}

		return C[n][k];
	}

	public static long binaryExponentiation(long x, long n) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = result * x;
			x = (x % mod * x % mod) % mod;
			n = n / 2;
		}
		return result;
	}

	public static int modularExponentiation(int x, int n, int M) {
		int result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static long modularExponentiation(long x, long n, long M) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}

	public static int modInverse(int A, int M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static long sie(long A, long M) {
		return modularExponentiation(A, M - 2, M);
	}

	public static boolean checkYear(int year) {
		if (year % 400 == 0)
			return true;

		if (year % 100 == 0)
			return false;

		if (year % 4 == 0)
			return true;
		return false;
	}

	public static boolean isPrime(int n) {

		if (n <= 1)
			return false;
		if (n <= 3)
			return true;

		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6) {
			if (n % i == 0 || n % (i + 2) == 0)
				return false;
		}

		return true;
	}

	static class pair implements Comparable<pair>

	{
		Long x, y;

		pair(long x, long y) {
			this.x = x;
			this.y = y;
		}

		public int compareTo(pair o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);

			return result;
		}

		public String toString() {
			return x + " " + y;
		}

		public boolean equals(Object o) {
			if (o instanceof pair) {
				pair p = (pair) o;
				if(p.x-x==0 && p.y-y==0)
					return true;
				else
				return false;
			}
			return false;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode();
		}

	}

	static class triplet implements Comparable<triplet> {
		Integer x, y, z;

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

		public int compareTo(triplet o) {
			int result = x.compareTo(o.x);
			if (result == 0)
				result = y.compareTo(o.y);
			if (result == 0)
				result = z.compareTo(o.z);

			return result;
		}

		public boolean equlas(Object o) {
			if (o instanceof triplet) {
				triplet p = (triplet) o;
				return x == p.x && y == p.y && z == p.z;
			}
			return false;
		}

		public String toString() {
			return x + " " + y + " " + z;
		}

		public int hashCode() {
			return new Long(x).hashCode() * 31 + new Long(y).hashCode() + new Long(z).hashCode();
		}
	}

	static class query implements Comparable<query> {
		Integer l,r, x, idx, tp;

		query(int l, int r, int x, int id, int tp)
		{
			this.l = l ;
			this.r = r;
			this.x = x;
			this.idx = id;
			this.tp = tp;
		}

		public int compareTo(query o) {
			int result = x.compareTo(o.x);

			return result;
		}

	}

	/*
	 * static class node implements Comparable<node>
	 *
	 * { Integer x, y, z; node(int x,int y, int z) { this.x=x; this.y=y; this.z=z; }
	 *
	 * public int compareTo(pair o) { int result = x.compareTo(o.x); if(result==0)
	 * result = y.compareTo(o.y); if(result==0) result = z.compareTo(z); return
	 * result; }
	 *
	 * @Override public int compareTo(node o) { // TODO Auto-generated method stub
	 * return 0; } }
	 */
}