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

public class A {
	static int[] dx = {0,0,1,-1};
	static int[] dy = {1,-1,0,0};
	static int N,M;
	public static void main(String[] args) {
		MScanner sc = new MScanner();
		PrintWriter out = new PrintWriter(System.out);
		N = sc.nextInt();
		M = sc.nextInt();
		int[][] grid = sc.nextInt(N,M);
		int NM = N*M;
		MinCostFlow MCF = new MinCostFlow(NM);
		int pos = 0;
		for(int a=0;a<N;a++){
			for(int b=0;b<M;b++){
				if((a+b)%2==0){
					MCF.add(MCF.s, pos, 1, 0);
					for(int d=0;d<4;d++){
						int ny = dy[d]+a;
						int nx = dx[d]+b;
						if(ny<0||ny>=N||nx<0||nx>=M)
							continue;
						if(grid[a][b]==grid[ny][nx])MCF.add(pos, magic(ny,nx), 1, 0);
						else MCF.add(pos, magic(ny,nx), 1, 1);
					}
				}
				else if((a+b)%2==1)MCF.add(pos, MCF.t, 1, 0);
				pos++;
			}
		}
		out.println(MCF.getFlow()[1]);
		out.close();
	}

	private static int magic(int ny, int nx) {
		return ny*M + nx;
	}

	static class MinCostFlow {
		  public static int MINCOSTFLOW = 0, MINCOSTMAXFLOW = 1;
		  public int s, t;
		  int N, ss, tt;
		  public long oo = (long) 1e12;
		  long[] ex;
		  ArrayList<Edge>[] adjj;
		  public Edge[][] adj;

		  public MinCostFlow(int NN) {
		    this(NN, MINCOSTMAXFLOW);
		  }

		  public MinCostFlow(int NN, int flowType) {
		    N = (tt = (ss = (t = (s = NN) + 1) + 1) + 1) + 1;
		    adj = new Edge[N][0];
		    adjj = new ArrayList[N];
		    for (int i = 0; i < N; i++)
		      adjj[i] = new ArrayList<Edge>();
		    ex = new long[N];
		    add(t, s, oo, -oo / 10 * flowType);
		  }

		  public void add(int i, int j, long cap, long cost) {
		    Edge fwd = new Edge(i, j, cap, 0, cost);
		    Edge rev = new Edge(j, i, 0, 0, -cost);
		    adjj[i].add(rev.rev = fwd);
		    adjj[j].add(fwd.rev = rev);
		  }

		  public long[] getFlow() {
		    preFlow();
		    for (int i = 0; i < N; i++)
		      adj[i] = adjj[i].toArray(adj[i]);
		    boolean[] canU = new boolean[N], hasU = new boolean[N];
		    long[] dist = new long[N], width = new long[N];
		    Edge[] prev = new Edge[N];
		    while (true) {
		      Arrays.fill(dist, oo);
		      dist[ss] = 0;
		      width[ss] = oo;
		      boolean updated = hasU[ss] = true;
		      while (updated) {
		        updated = false;
		        for (int i = 0; i < N; hasU[i++] = false)
		          canU[i] = hasU[i];
		        for (int i = 0; i < N; i++)
		          if (canU[i])
		            for (Edge e : adj[i])
		              if (e.flow != e.cap && dist[e.j] > dist[e.i] + e.cost) {
		                dist[e.j] = dist[e.i] + (prev[e.j] = e).cost;
		                width[e.j] = Math.min(width[e.i], e.cap - e.flow);
		                hasU[e.j] = updated = true;
		              }
		      }
		      if (dist[tt] >= oo)
		        break;
		      for (Edge e = prev[tt]; e != null; e = prev[e.i])
		        e.rev.flow = -(e.flow += width[tt]);
		    }
		    long flow = 0, cost = 0;
		    for (Edge e : adj[s])
		      if (e.flow > 0)
		        flow += e.flow;
		    for (int i = 0; i < N; i++)
		      for (Edge e : adj[i])
		        if (e.flow > 0 && e.i != t && e.j != s && e.i < ss && e.j < ss)
		          cost += e.flow * e.cost;
		    return new long[] { flow, cost };
		  }

		  public void preFlow() {
		    for (int i = 0; i < N; i++)
		      for (Edge e : adjj[i])
		        if (e.cost < 0 && e.cap - e.flow > 0) {
		          ex[e.i] -= e.cap - e.flow;
		          ex[e.j] += e.cap - e.flow;
		          e.rev.flow = -(e.flow = e.cap);
		        }
		    for (int i = 0; i < N; i++)
		      if (ex[i] > 0)
		        add(ss, i, ex[i], -oo);
		      else if (ex[i] < 0)
		        add(i, tt, -ex[i], -oo);
		    Arrays.fill(ex, 0);
		  }

		  public class Edge {
		    public int i, j;
		    public long cap, flow, cost;
		    Edge rev;

		    Edge(int ii, int jj, long cc, long ff, long C) {
		      i = ii;
		      j = jj;
		      cap = cc;
		      flow = ff;
		      cost = C;
		    }
		  }
		}

	static class MScanner{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public MScanner(){
			stream = System.in;
			//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[] nextInt(int N){
			int[] ret = new int[N];
			for(int a=0;a<N;a++)
				ret[a] = nextInt();
			return ret;
		}
		int[][] nextInt(int N, int M){
			int[][] ret = new int[N][M];
			for(int a=0;a<N;a++)
				ret[a] = nextInt(M);
			return ret;
		}
		long nextLong(){
			return Long.parseLong(next());
		}
		long[] nextLong(int N){
			long[] ret = new long[N];
			for(int a=0;a<N;a++)
				ret[a] = nextLong();
			return ret;
		}
		double nextDouble(){
			return Double.parseDouble(next());
		}
		double[] nextDouble(int N){
			double[] ret = new double[N];
			for(int a=0;a<N;a++)
				ret[a] = nextDouble();
			return ret;
		}
		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[] next(int N){
			String[] ret = new String[N];
			for(int a=0;a<N;a++)
				ret[a] = next();
			return ret;
		}
		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();
		}
		String[] nextLine(int N){
			String[] ret = new String[N];
			for(int a=0;a<N;a++)
				ret[a] = nextLine();
			return ret;
		}

	}
}


import java.math.BigDecimal;
import java.util.Scanner;

public class Main {
    static BigDecimal pow(BigDecimal a, BigDecimal b) {
        double bDouble = b.doubleValue();
        int integerPortion = (int) bDouble;
        double fractionalPortion = bDouble - integerPortion;
        BigDecimal aToIntegerPortion = a.pow(integerPortion);
        BigDecimal aToFractionalPortion = new BigDecimal(Math.pow(a.doubleValue(), fractionalPortion));
        return aToIntegerPortion.multiply(aToFractionalPortion);
    }

    static BigDecimal log(BigDecimal value) {
        return new BigDecimal(Math.log(value.doubleValue()));
    }

    public static void main (String[] args) {
        Scanner sc = new Scanner(System.in);
        BigDecimal x = new BigDecimal(sc.next());
        BigDecimal y = new BigDecimal(sc.next());
        BigDecimal z = new BigDecimal(sc.next());
        sc.close();

        BigDecimal[] logValues = {
                pow(y, z).multiply(log(x)),
                pow(z, y).multiply(log(x)),
                z.multiply(y).multiply(log(x)),
                y.multiply(z).multiply(log(x)),
                pow(x, z).multiply(log(y)),
                pow(z, x).multiply(log(y)),
                z.multiply(x).multiply(log(y)),
                x.multiply(z).multiply(log(y)),
                pow(x, y).multiply(log(z)),
                pow(y, x).multiply(log(z)),
                y.multiply(x).multiply(log(z)),
                x.multiply(y).multiply(log(z))
        };

        int greatestIndex = 0;
        for (int i = 1; i < logValues.length; i++) {
            if (logValues[i].compareTo(logValues[greatestIndex]) > 0) greatestIndex = i;
        }

        String[] valueRepresentations = {
                "x^y^z",
                "x^z^y",
                "(x^y)^z",
                "(x^z)^y",
                "y^x^z",
                "y^z^x",
                "(y^x)^z",
                "(y^z)^x",
                "z^x^y",
                "z^y^x",
                "(z^x)^y",
                "(z^y)^x"
        };

        System.out.print(valueRepresentations[greatestIndex]);
    }
}


// package QS.AA.NetworkFlow;

// B. Help General
// https://codeforces.com/problemset/problem/142/B
import java.util.*;
import java.io.*;

public class CF_142B {
	public static void main(String[] args) throws IOException {
		java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(System.in));
		String[] tokens = br.readLine().trim().split("\\s");
		int n = Integer.parseInt(tokens[0]);
		int m = Integer.parseInt(tokens[1]);
		if (n > m) {int temp = n; n = m; m = temp;}
		int ans = 0;
		if (n == 1 || m == 1) {
			ans = m * n;
		} else if (n == 2 && m >= 2) {
			ans = m - (m % 4) + Math.min(m % 4, 2) * 2;
		} else {
			ans = (m * n + 1) / 2;
		}
		System.out.println(ans);
	}
}


import java.util.Scanner;
import java.util.Arrays;
import java.util.*;
import java.lang.*;

public class Code {

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		ArrayList<Integer> list = new ArrayList<>();
		HashSet<Integer> hash = new HashSet<>();
		int result =  0;
		int n = cin.nextInt();
		cin.nextLine();

		int[] arr = new int[n];

		for(int i = 0;i<n;i++) {
			arr[i] = cin.nextInt();
		}
					if(n ==1 ) {
						System.out.println(arr[0]);
						return;
					}

		Arrays.sort(arr);

		System.out.println(arr[n/2]);

		cin.close();
	}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Locale;
import java.util.PriorityQueue;
import java.util.Random;
import java.util.StringTokenizer;

public class C {

	private void solve() throws IOException {
		long n = nextLong();

		if (n % 3 != 0) {
			println("0");
			return;
		}

		n /= 3;

		int res = 0;
		for (long i = 1; i * i * i <= n; i++) {
			if (n % i != 0) {
				continue;
			}

			for (long a = 1; a * a <= n && a + a <= i; a++) {
				long b = i - a;
				long m = n / i;
				long d = i * i - 4 * (a * b - m);

				if (d <= 0) {
					continue;
				} else {
					long sq = (long)Math.sqrt(d);
					if (sq * sq != d || sq < i || (sq - i) % 2 == 1) {
						continue;
					}

					long c = (sq - i) / 2;
					if (c < a || c < b) {
						continue;
					}

					if (a == b && a == c) {
						res++;
					} else if (a != b && a != c && b != c) {
						res += 6;
					} else {
						res += 3;
					}
				}
			}
		}

		println(res);
	}

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

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

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

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

	private void print(Object o) {
		writer.print(o);
	}

	private void println(Object o) {
		writer.println(o);
	}

	private void printf(String format, Object... o) {
		writer.printf(format, o);
	}

	public static void main(String[] args) {
		long time = System.currentTimeMillis();
		Locale.setDefault(Locale.US);
		new C().run();
		System.err.printf("%.3f\n", 1e-3 * (System.currentTimeMillis() - time));
	}

	BufferedReader reader;
	StringTokenizer tokenizer;
	PrintWriter writer;

	private void run() {
		try {
			reader = new BufferedReader(new InputStreamReader(System.in));
			writer = new PrintWriter(System.out);
			solve();
			reader.close();
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(13);
		}
	}
}


import java.util.Scanner;

public class Future {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		long n = in.nextLong();
		long a = in.nextLong();
		long b = in.nextLong();
		long c = in.nextLong();
		long k = 0;
		if (b - c < a && n >= b) {
			k = (n-b)/(b-c) + 1;
			n -= k * (b-c);
			k += n/a;
		}
		else if(n < b || b - c >= a) {
			k = n/a;
		}
		System.out.println(k);
		in.close();
	}

}


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

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Lokesh Khandelwal
 */
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);
		TaskB solver = new TaskB();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskB {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int n = in.nextInt(), d = in.nextInt(), i, a[] = new int[n], total = 0, j;
        for(i=0;i<n;i++) {
            a[i] = in.nextInt();
            total += a[i];
        }
        boolean canSum[] = new boolean[total+1];
        canSum[0] = true;
        for(i=0;i<n;i++) {
            for(j=total;j>=a[i];j--) {
                if(canSum[j - a[i]])
                    canSum[j] = true;
            }
        }
        int max = 0, ans = 0;
        while (true) {
            int nmax = max;
            for(i=max+1;i<=total && i<=max+d;i++) {
                if(canSum[i])
                    nmax = i;
            }
            if(nmax == max)
                break;
            ans++;
            max = nmax;
        }
        out.printLine(max +" "+ans);
    }
}

class InputReader
{
    BufferedReader in;
    StringTokenizer tokenizer=null;

    public InputReader(InputStream inputStream)
    {
        in=new BufferedReader(new InputStreamReader(inputStream));
    }
    public String next()
    {
        try{
            while (tokenizer==null||!tokenizer.hasMoreTokens())
            {
                tokenizer=new StringTokenizer(in.readLine());
            }
            return tokenizer.nextToken();
        }
        catch (IOException e)
        {
            return null;
        }
    }
    public int nextInt()
    {
        return Integer.parseInt(next());
    }
    }

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(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.math.*;
import java.util.Scanner;
public class Main {
    final static Integer MOD = 1000000009;
    public static BigInteger Com(int a,Integer n){
        if(a==0) return BigInteger.ONE;
        if(a==n) return BigInteger.ONE;
        BigInteger fenz = new BigInteger(n.toString());
        BigInteger fenm = BigInteger.ONE;
        //System.out.println(fenz + " "+fenm);
        for(int i=1;i<a; i++){
            n--;
            BigInteger next = new BigInteger(n.toString());
            //System.out.println(next);
            fenz = fenz.multiply(next);
            //System.out.println(fenz);

        }
        for(Integer i=2;i<=a;i++){
            BigInteger next = new BigInteger(i.toString());
            fenm = fenm.multiply(next);
        }
        return fenz.divide(fenm);
    }
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        BigInteger BigMod = new BigInteger(MOD.toString());
        while(in.hasNextInt()){
            int n = in.nextInt() ;
            int w = in.nextInt();
            int b = in.nextInt();
            //System.out.println(n+" "+w+" "+b);
            //BigInteger  res = BigInteger.ZERO;
            long res = 0;
            int Bnum = b;

                if(w < 2) continue;
                long fact_w = fact(w);
                long len_w = w - 1;
                long fact_b = fact(Bnum);
                res = res + ( fact_w * len_w ) % MOD ;
                res = (res * fact_b) % MOD;
                BigInteger mul = Com(n-3,b-1+w-2);
                //System.out.println(n-2+""mul);
                mul = mul.mod(BigMod);
                //System.out.println(mul);
                String smul = mul.toString();
                res = res * Integer.parseInt(smul) % MOD;

            System.out.println(res);
        }
    }
    private static long fact(int wnum) {
        long ans=1;
        for(int i=1;i<=wnum;i++){
            ans*=i;
            ans%=MOD;
        }
        return ans;
    }
}


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

/**
 * Created by Firеfly on 12/18/2016.
 */
public class code {
    public static void main(String[] args) throws IOException {
        Woorker worker = new Woorker();
    }
}
class Woorker {
    Woorker() throws IOException {
        FastScannerqq fs = new FastScannerqq(new InputStreamReader(System.in));
        int s = fs.nextInt();
        int x1 = fs.nextInt();
        int x2 = fs.nextInt();
        int t2 = fs.nextInt();
        int t1 = fs.nextInt();
        int p = fs.nextInt();
        int d =fs.nextInt();
        int timeto = Math.abs(x1-x2)*t1;
        if (t1<=t2) System.out.println(timeto);
        else {
            int timeto1;
            if ((p>=x1 && d == -1) || (p<=x1 && d == 1)) timeto1 = Math.abs(p-x1)*t2;
            else if (p>=x1 && d==1){ timeto1 = (2*s-p-x1)*t2; d = -1; }
            else {timeto1 = (p+x1)*t2; d = 1; }
            if (x2>=x1 && d == 1)
                timeto1+=(x2-x1)*t2;
            else if (x2>=x1 && d==-1)
                timeto1+=(x1+x2)*t2;
            else if (x2<=x1 && d==-1)
                timeto1+=(x1-x2)*t2;
            else timeto1+=(2*s-x1-x2)*t2;
            System.out.println(Math.min(timeto, timeto1));

        }

    }
}

class FastScannerqq {
    BufferedReader br;
    StringTokenizer stok;

    FastScannerqq(InputStreamReader fr) {
        br = new BufferedReader(fr);
    }

    String nextToken() throws IOException {
        while (stok == null || !stok.hasMoreTokens()) {
            String s = br.readLine();
            if (s == null)
                return null;
            stok = new StringTokenizer(s);
        }
        return stok.nextToken();
    }

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

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

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

    char nextChar() throws IOException {
        return (char) br.read();
    }

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


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

public class Prob_Hanoi{
    public static long V[][];
    public static boolean Visited[][][];
    public static long MEMO[][][];
    public static void main(String args[]){
        Scanner input=new Scanner(System.in);
        V=new long[3][];
        V[0]=new long[3];
        V[1]=new long[3];
        V[2]=new long[3];
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                V[i][j]=input.nextLong();
            }
        }
        int n=input.nextInt();
        Visited=new boolean[n+1][][];
        MEMO=new long[n+1][][];
        for(int i=0;i<=n;i++){
            Visited[i]=new boolean[3][];
            MEMO[i]=new long[3][];
            for(int j=0;j<3;j++){
                Visited[i][j]=new boolean[3];
                for(int k=0;k<3;k++){
                    Visited[i][j][k]=false;
                }
                MEMO[i][j]=new long[3];
            }
        }
        onlyOne();
        for(int i=1;i<n;i++){
            for(int j=0;j<3;j++){
                for(int k=0;k<3;k++){
                    if(j!=k){
                     //   System.out.println(i+""+j+""+k+")="+DP(i,j,k));
                    }
                }
            }
        }
        System.out.println(DP(n,0,2));

    }
    public static void onlyOne(){
        for(int i=0;i<3;i++){
            for(int j=0;j<3;j++){
                    if(i==j) continue;
                    int k=0+1+2-i-j;
                    MEMO[1][i][j]=Math.min(V[i][j],V[i][k]+V[k][j]);
                    Visited[1][i][j]=true;
            }
        }
    }
    public static long DP(int n,int i,int j){
        if(Visited[n][i][j])
            return MEMO[n][i][j];
        int k=0+1+2-i-j;
        MEMO[n][i][j]=Math.min(DP(n-1,i,k)+V[i][j]+DP(n-1,k,j),
                               DP(n-1,i,j)+V[i][k]+DP(n-1,j,i)+V[k][j]+DP(n-1,i,j));
       Visited[n][i][j]   =true;
       return MEMO[n][i][j];
    }
}


import java.util.*;

public class PostOffice {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long d = 0;
		long a, b, t, k;
		Scanner sc = new Scanner(System.in);
		d = sc.nextLong();
		k = sc.nextLong();
		a = sc.nextLong();
		b = sc.nextLong();
		t = sc.nextLong();

		long answer = -1;

		if(d<k){
			answer = d*a;
		}

		else if(k*a+t >= k*b) {
			answer = k*a + (d-k)*b;
		}
		else{
			long q = d/k;
			long r = d - q*k;
			if(t+r*a<r*b){
				answer = (k*a+t)*q + r*a;
			}
			else{
				answer = (k*a+t)*q+r*b-t;
			}
		}
		System.out.println(answer);
	}

}


// practice with rainboy
import java.io.*;
import java.util.*;

public class CF946F extends PrintWriter {
	CF946F() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF946F o = new CF946F(); o.main(); o.flush();
	}

	static final int MD = 1000000007;
	long power(int a, int k) {
		if (k == 0)
			return 1;
		long p = power(a, k >> 1);
		p = p * p % MD;
		if ((k & 1) == 1)
			p = p * a % MD;
		return p;
	}
	void main() {
		int n = sc.nextInt();
		int x = sc.nextInt();
		byte[] cc = sc.next().getBytes();
		if (x == 0) {
			println(n == 1 && cc[0] == '0' ? 1 : 0);
			return;
		}
		int[] ff = new int[x + 1];
		ff[0] = ff[1] = 1;
		for (int i = 2; i <= x; i++)
			ff[i] = (ff[i - 1] + ff[i - 2]) % (MD - 1);
		for (int i = 0; i <= x; i++)
			ff[i] = (int) power(2, ff[i]);
		int[][][] ds = new int[x + 1][n][n + 1];
		for (int l = 0; l < n; l++) {
			ds[0][l][l] = ds[1][l][l] = 1;
			ds[0][l][l + 1] = cc[l] == '0' ? 1 : 0;
			ds[1][l][l + 1] = cc[l] == '1' ? 1 : 0;
		}
		for (int i = 2; i <= x; i++)
			for (int l = 0; l < n; l++)
				for (int r = l; r < n; r++) {
					long z = 0;
					for (int m = l; m <= r; m++)
						z = (z + (long) ds[i - 1][l][m] * ds[i - 2][m][r]) % MD;
					ds[i][l][r] = (int) z;
				}
		int[][] dp = new int[x + 1][n];
		int[][] dq = new int[x + 1][n];
		if (n > 1) {
			dp[0][n - 1] = ds[0][n - 1][n];
			dp[1][n - 1] = ds[1][n - 1][n];
			for (int i = 2; i <= x; i++)
				for (int l = 1; l < n; l++) {
					long z = (long) dp[i - 1][l] * ff[i - 2] % MD;
					for (int m = l; m < n; m++)
						z = (z + (long) ds[i - 1][l][m] * dp[i - 2][m]) % MD;
					dp[i][l] = (int) z;
				}
			dq[0][1] = ds[0][0][1];
			dq[1][1] = ds[1][0][1];
			for (int i = 2; i <= x; i++)
				for (int r = 1; r < n; r++) {
					long z = (long) ff[i - 1] * dq[i - 2][r] % MD;
					for (int m = r; m > 0; m--)
						z = (z + (long) dq[i - 1][m] * ds[i - 2][m][r]) % MD;
					dq[i][r] = (int) z;
				}
		}
		int[] dr = new int[x + 1];
		dr[0] = ds[0][0][n];
		dr[1] = ds[1][0][n];
		for (int i = 2; i <= x; i++) {
			long z = ((long) dr[i - 1] * ff[i - 2] + (long) ff[i - 1] * dr[i - 2]) % MD;
			for (int m = 1; m < n; m++)
				z = (z + (long) dq[i - 1][m] * dp[i - 2][m]) % MD;
			dr[i] = (int) z;
		}
		println(dr[x]);
	}
}


import java.io.*;
import java.util.Arrays;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.function.Function;

public class E {
    String fileName = "E";

    public int n, m;

    public static class Event implements Comparable<Event> {
        public static final int OPEN_TYPE = 0;
        public static final int POINT_TYPE = 1;
        public static final int CLOSE_TYPE = 2;

        public int x, type;

        public Event(int x, int type) {
            this.x = x;
            this.type = type;
        }

        @Override
        public int compareTo(Event event) {
            if (Integer.compare(x, event.x) != 0)
                return Integer.compare(x, event.x);
            else return Integer.compare(type, event.type);
        }
    }

    public static final class Node {
        public int l, r;
        public int max, maxInd;

        public Node leftNode, rightNode;

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

    public void relax(Node root) {
        if (root.leftNode.max > root.rightNode.max) {
            root.max = root.leftNode.max;
            root.maxInd = root.leftNode.maxInd;
        } else {
            root.max = root.rightNode.max;
            root.maxInd = root.rightNode.maxInd;
        }
    }

    public Node build(int l, int r, Function<Integer, Integer> getItem) {
        Node res = new Node(l, r);
        if (l == r) {
            res.max = getItem.apply(l);
            res.maxInd = l;
        } else {
            int m = (r + l) / 2;
            res.leftNode = build(l, m, getItem);
            res.rightNode = build(m + 1, r, getItem);
            relax(res);
        }
        return res;
    }

    public void set(Node root, int ind, int val) {
        if (ind < root.l || ind > root.r)
            return;
        if (root.l == root.r) {
            root.max = val;
            return;
        }
        set(root.leftNode, ind, val);
        set(root.rightNode, ind, val);
        relax(root);
    }

    public static class QueryResult {
        public int max, maxInd;

        public QueryResult(int max, int maxInd) {
            this.max = max;
            this.maxInd = maxInd;
        }

        public QueryResult(QueryResult first, QueryResult second) {
            if (first.max > second.max) {
                this.max = first.max;
                this.maxInd = first.maxInd;
            } else {
                this.max = second.max;
                this.maxInd = second.maxInd;
            }
        }
    }

    public QueryResult query(Node root, int l, int r) {
        if (r == -1)
            return new QueryResult(0, -1);
        if (r < root.l || l > root.r)
            return new QueryResult(Integer.MIN_VALUE, -1);
        if (l <= root.l && r >= root.r) {
            return new QueryResult(root.max, root.maxInd);
        }
        return new QueryResult(query(root.leftNode, l, r), query(root.rightNode, l, r));
    }

    public int[] getLens(int[] a) {
        Node root = build(0, n, ind -> 0);
        int[] len = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            int curVal = a[i];
            int prevLen = query(root, 0, curVal).max;
            len[i] = prevLen + 1;
            if (query(root, curVal, curVal).max < len[i])
                set(root, curVal, len[i]);
        }
        return len;
    }

    public void solve() throws IOException {
        n = nextInt();
        m = nextInt();
        Event[] events = new Event[2 * n + m];
        for (int i = 1; i <= m; i++) {
            events[i - 1] = new Event(i, Event.POINT_TYPE);
        }
        for (int i = 0; i < n; i++) {
            int l = nextInt();
            int r = nextInt();
            events[m + 2 * i] = new Event(l, Event.OPEN_TYPE);
            events[m + 2 * i + 1] = new Event(r, Event.CLOSE_TYPE);
        }
        Arrays.sort(events);
        int[] cnt = new int[m];
        int balance = 0;
        for (int i = 0; i < events.length; i++) {
            Event curEvent = events[i];
            if (curEvent.type == Event.OPEN_TYPE) {
                balance++;
            } else if (curEvent.type == Event.CLOSE_TYPE) {
                balance--;
            } else if (curEvent.type == Event.POINT_TYPE) {
                cnt[curEvent.x - 1] = balance;
            }
        }
        int[] lenUp = getLens(cnt);
        int[] newCnt = new int[cnt.length];
        for (int i = 0; i < cnt.length; i++) {
            newCnt[i] = cnt[cnt.length - i - 1];
        }
        int[] lenDown = getLens(newCnt);
        int[] revLenDown = new int[lenDown.length];
        for (int i = 0; i < lenDown.length; i++) {
            revLenDown[i] = lenDown[lenDown.length - i - 1];
        }
        int max = 0;
        for (int i = 0; i < lenDown.length; i++) {
            int cur = lenUp[i] + revLenDown[i] - 1;
            max = Math.max(max, cur);
        }
        out.print(max);
    }

    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);

            solve();

            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    BufferedReader br;
    StringTokenizer in;
    PrintWriter out;

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

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

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

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

    public static void main(String[] args) throws IOException {
        Locale.setDefault(Locale.US);
        new E().run();
    }
}


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

import static java.lang.Math.*;

public class Main {
    BufferedReader br;
    StringTokenizer in;
    PrintWriter pw;
    Random r;
    int INF = (int) 1e9;
    int mod = (int) (1e9 + 7);
    //int p = 26;
    ArrayList<Integer> g[];

    void end(int a, int n) {
        if ((int) Math.pow(2, a) != n) pw.print(a);
        else pw.print("Final!");
        pw.close();
        System.exit(0);
    }

    class node {
        int val;
        int m;
        int size;
        int prior;
        node L;
        node R;

        public node(int v) {
            val = v;
            prior = r.nextInt();
            size = 1;
            L = null;
            R = null;
        }
    }

    int sgs(node c) {
        if (c == null) return 0;
        return c.size;
    }

    int sgm(node c) {
        if (c == null) return INF;
        return c.m;
    }

    void relax(node c) {
        if (c == null) return;
        c.size = 1 + sgs(c.L) + sgs(c.R);
    }

    class pair implements Comparable<pair> {
        int a;
        int b;

        public pair(int aa, int bb) {
            a = aa;
            b = bb;
        }

        @Override
        public int compareTo(pair o) {
            if (a != o.a) return a - o.a;
            return b - o.b;
        }
    }

    class road {
        int to;
        int w;

        public road(int tto, int ww) {
            to = tto;
            w = ww;
        }

        public road() throws IOException {
            to = nextInt();
            w = nextInt();
        }
    }

    void readG(int n, int m) throws IOException {
        g = new ArrayList[n];
        for (int i = 0; i < n; i++) {
            g[i] = new ArrayList<>();
        }
        for (int i = 0; i < m; i++) {
            int a = nextInt() - 1;
            int b = nextInt() - 1;
            int w = nextInt();
//            g[a].add(new road(b, w));
//            g[b].add(new road(a, w));
        }
    }

    int p[];
    int d[];

    void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        event[] p = new event[n * 2];
        for (int i = 0; i < n; i++) {
            int l = nextInt();
            int r = nextInt();
            p[i] = new event(l, 1);
            p[i + n] = new event(r, -1);
        }
        int q = p.length;
        int b = 0;
        Arrays.sort(p);
        int bal[] = new int[m + 1];
        int prev = 0;
        for (int i = 0; i < q; i++) {
            event a = p[i];
            if (a.t == -1) {
                for (int j = prev + 1; j <= a.time; j++) {
                    bal[j] = b;
                }
                prev = a.time;
            } else {
                for (int j = prev + 1; j < a.time; j++) {
                    bal[j] = b;
                }
                prev = a.time - 1;
            }
            b += a.t;
        }
//        for (int i = 1; i <= m; i++) {
//            pw.print(bal[i]);
//        }
        int revbal[] = new int[m + 1];
        for (int i = 1; i <= m; i++) {
            revbal[i] = bal[m + 1 - i];
        }
        int nvp[] = getnvp(bal);
        int rnvp[] = getnvp(revbal);
        int ans = 0;
        for (int i = 1; i <= m; i++) {
            int z = nvp[i];
            int w = rnvp[m - i];
            int sum = z + w;
            ans = max(ans, sum);
        }
        pw.print(ans);
    }

    int[] getnvp(int a[]) {
        int n = a.length;
        int d[] = new int[n + 1];
        int ans[] = new int[n];
        Arrays.fill(d, INF);
        d[0] = -INF;
        int last = 0;
        for (int i = 1; i < n; i++) {
            ans[i] = ans[i - 1];
            int c = a[i];
            int l = 0;
            int r = last + 1;
            while (l + 1 != r) {
                int m = (l + r) / 2;
                if (d[m] <= c) l = m;
                else r = m;
            }
            if (d[r] == INF) {
                ans[i]++;
                last++;
            }
            d[r] = min(d[r], c);
        }
        return ans;
    }

    class event implements Comparable<event> {
        int time;
        int t;

        public event(int ttime, int tt) {
            time = ttime;
            t = tt;
        }

        @Override
        public int compareTo(event o) {
            if (time != o.time) return time - o.time;
            else return o.t - t;
        }
    }

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

    void run() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new OutputStreamWriter(System.out));
        r = new Random(5);
        solve();
        pw.close();
    }

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

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

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


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.lang.reflect.Array;
import java.util.*;

public class Main {
    ArrayList<ArrayList<Integer>> q;
    boolean[] used;

    public void solve() throws IOException {
        int n = nextInt();
        int m = nextInt();
        int[] a = new int[m + 1];
        for (int i = 0; i < n; i++) {
            a[nextInt() - 1]++;
            a[nextInt()]--;
        }
        for (int i = 1; i < m; i++) {
            a[i] += a[i - 1];
        }
        int[] d = new int[m + 1];
        Arrays.fill(d, Integer.MAX_VALUE);
        int k = 0;
        int[] v1 = new int[m + 2];
        int[] v2 = new int[m + 2];
        for (int i = 0; i < m; i++) {
            int l = 0;
            int r = m;
            while (r - l > 1) {
                int m1 = (r + l) / 2;
                if (d[m1] > a[i]) {
                    r = m1;
                } else {
                    l = m1;
                }
            }
            if (d[l] <= a[i]) {
                l++;
            }
            if (d[l] == Integer.MAX_VALUE){
                k++;
            }
            d[l] = a[i];
            v1[i] = k;
        }
        k = 0;
        int max = 0;
        Arrays.fill(d,Integer.MAX_VALUE);
        for (int i = m - 1; i >= 0; i--) {
            int l = 0;
            int r = m;
            while (r - l > 1) {
                int m1 = (r + l) / 2;
                if (d[m1] > a[i]) {
                    r = m1;
                } else {
                    l = m1;
                }
            }
            if (d[l] <= a[i]) {
                l++;
            }
            if (d[l] == Integer.MAX_VALUE){
                k++;
            }
            d[l] = a[i];
            v2[i] = k;
            max = Math.max(max,v1[i] + v2[i + 1]);
        }
        max = Math.max(max,v2[0]);
        out.print(max);
    }

    BufferedReader br;
    StringTokenizer sc;
    PrintWriter out;

    String nextToken() throws IOException {
        while (sc == null || !sc.hasMoreTokens()) {
            try {
                sc = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                sc = null;
            }
        }
        return sc.nextToken();
    }

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

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

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

    public static void main(String[] args) throws IOException {
        Locale.setDefault(Locale.US);
        new Main().run();
    }

    public void run() throws IOException {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }
}


import java.util.LinkedList;
import java.util.Scanner;

public class Main {

	private void start() {
		Scanner in = new Scanner(System.in);

		int n;

		n = in.nextInt();

		if (n == 1) {
			System.out.println(0);
			return;
		}
		int k = Integer.MAX_VALUE;
		for (int i = 1; i < n; i++) {
			k = Math.min(k, calc(i, n));
		}
		System.out.println(k);
	}

	private int calc(int i, int n) {

		if (i == 1) {
			return n - 1;
		}

		int ret = 0;

		while (true) {
			if (i > n) {
				int t = i;
				i = n;
				n = t;
			}

			if (i == 1) {
				ret += n - 1;
				break;
			}

			if (n % i == 0) {
				return Integer.MAX_VALUE;
			}

			int q = n / i;
			ret += q;
			n = n - i * q;

			if (i == 1 && n == 1) {
				break;
			}
		}
		return ret;
	}

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


import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {

    public static void main(final String[] args) throws IOException {
        try(Scanner scan = new Scanner(System.in);
            PrintWriter print = new PrintWriter(System.out)) {
            final int n = scan.nextInt();
            final int l = scan.nextInt();
            final int r = scan.nextInt();
            final Floodlight[] floodlights = new Floodlight[n];
            for(int i = 0; i < n; ++i) {
                final int x = scan.nextInt();
                final int y = scan.nextInt();
                final double angle = scan.nextInt() / 180. * Math.PI;
                floodlights[i] = new Floodlight(x, y, angle);
            }
            print.println(calcMaxBeginSeg(l, r, floodlights));
        }
    }

    public static double calcMaxBeginSeg(final int left, final int right, final Floodlight[] floodlights) {
        if(right <= left) return 0.;
        final int n = floodlights.length;
        double maxLitRight[] = new double[1 << n];
        maxLitRight[0] = left;
        for(int mask = 1; mask < 1 << n; ++mask) {
            double result = left;
            for(int i = 0; i < n; ++i) {
                if(((mask >> i) & 1) == 1) {
                    result = Math.max(result, extendLitSeg(maxLitRight[mask ^ (1 << i)], floodlights[i], right));
                }
            }
            maxLitRight[mask] = result;
        }
        return maxLitRight[(1 << n) - 1] - left;
    }

    private static double extendLitSeg(final double left, final Floodlight light, final double maxRight) {
        if(left >= maxRight) return left;
        if(light.y <= 0.) throw new RuntimeException("light.y must be > 0");
        final double startAngle = Math.atan((left - light.getX()) / light.getY());
        final double endAngle = startAngle + light.angle;
        if(endAngle >= Math.PI / 2.) return maxRight;
        return Math.min(maxRight, light.getX() + light.getY() * Math.tan(endAngle));
    }

    public static class Floodlight {
        private final int x;
        private final int y;
        private final double angle;

        public Floodlight(final int x, final int y, final double angle) {
            this.x = x;
            this.y = y;
            this.angle = angle;
        }

        public int getX() {
            return x;
        }

        public int getY() {
            return y;
        }

        public double getAngle() {
            return angle;
        }
    }

    public static class NumberUtils {
        public static interface Factorizer {
            List<Integer> factorize(int number);
        }

        /**
         * thread safe Factorizer
         */
        public static Factorizer createSmallNumberFactorizer(final int upperBound) {
            return new SmallNumberFactorizer(upperBound);
        }

        /**
         * thread safe
         */
        private static class SmallNumberFactorizer implements Factorizer {
            private int[] divisors;
            private final int upperBound;
            private boolean prepared = false;

            /**
             * lazy
             * time complexity O(n * log(n) * log(log(n))
             * memory complexity O(n)
             */
            public SmallNumberFactorizer(final int upperBound) {
                this.upperBound = upperBound;
            }

            private synchronized void prepare() {
                divisors = new int[upperBound];
                Arrays.fill(divisors, 0);
                for(int i = 2; i * i < upperBound; ++i) {
                    if(divisors[i] == 0) {
                        for(int j = i * i; j < upperBound; j += i) {
                            if(divisors[j] == 0) {
                                divisors[j] = i;
                            }
                        }
                    }
                }
                prepared = true;
            }

            /**
             * complexity O(result)
             */
            public List<Integer> factorize(int number) {
                synchronized (this) {
                    if(!prepared) {
                        prepare();
                    }
                }
                final List<Integer> result = CollectionFactory.createArrayList();
                if(number < 2) return result;
                if(number >= upperBound) throw new RuntimeException("number should be less than upper bound");
                while(divisors[number] > 0) {
                    result.add(divisors[number]);
                    number /= divisors[number];
                }
                result.add(number);
                return result;
            }
        }
    }

    public static class CollectionFactory {
        public static<T> List<T> createArrayList() {
            return new ArrayList<>();
        }

        public static<T> List<T> createArrayList(final int capacity) {
            return new ArrayList<>(capacity);
        }
    }

    public static class CollectionUtils {
        public static<T> List<T> unique(final List<T> list) {
            final List<T> result = CollectionFactory.createArrayList();
            T p = null;
            for(T elem : list) {
                if(!elem.equals(p)) {
                    result.add(elem);
                    p = elem;
                }
            }
            return result;
        }

        public static<T extends Comparable<T>> T max(final List<T> list, final T lowerBound) {
            T result = lowerBound;
            for(T elem : list) {
                if(elem.compareTo(result) > 0) {
                    result = elem;
                }
            }
            return result;
        }
    }

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class GoldenAge {

    public static void main(String[] args) {
        FastReader read = new FastReader ()  ;
        long x = read.nextLong();
        long y = read.nextLong();
        long b = read.nextLong();
        long e = read.nextLong();
        ArrayList<Long> xl = new ArrayList<>();
        ArrayList<Long> yl = new ArrayList<>();
        ArrayList<Long> list = new ArrayList<>();

        long xp = 1 ;
        long yp = 1 ;

        while (e / x >= xp )
        {

            xl.add(xp );
            xp *= x;
        }
        xl.add(xp);
        while ( e / y >= yp  ){

                yl.add(yp);

                yp *= y ;

        }
        yl.add(yp);
        long tmp1 , tmp2 ;
        for (int i = 0; i < xl.size(); i++) {
               tmp1 = xl.get(i);
            for (int j = 0; j < yl.size(); j++) {
                tmp2 = yl.get(j);
                if(tmp1 + tmp2 >= b && tmp1 + tmp2 <= e ){
                list.add(tmp1 + tmp2 );
                }
            }
        }
        list.add(b-1);
        list.add(e+1);
        Collections.sort(list);
        long max = 0  ;

        for (int i = 1; i < list.size(); i++) {
            max = Math.max(max, list.get(i) - list.get(i-1) -1 );
        }
        System.out.println(max);
    }

}

  class FastReader{
    BufferedReader br ;
    StringTokenizer st;

    public FastReader(){
        InputStreamReader inr =new InputStreamReader(System.in);
        br=new BufferedReader(inr);

    }

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

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

    }

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

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


//package round81;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
//	String INPUT = "9 3 3\r\n" +
//	"4 3 1\r\n" +
//	"2 3 3";
	String INPUT = "8 10 10\r\n" +
	"9 10 10\r\n" +
	"10 10 10";
//	String INPUT = "1 1 1 2 1 10 5 1 1";

	void solve()
	{
		int[][] s = new int[3][4];
		for(int i = 0;i < 3;i++){
			for(int j = 0;j < 3;j++){
				s[i][j] = ni();
			}
		}

		int ct = 0;
		int[] iord = new int[9];
		for(int j = 0;j < 9;j++)iord[j] = j;
		gmax = 0;
		do{
			if(iord[1] < iord[2] && iord[4] < iord[5] && iord[7] < iord[8]){
				int[] ord = new int[9];
				for(int j = 0;j < 9;j++){
					ord[iord[j]] = j;
				}
				int[] u = new int[3];
				outer:
				for(int i = 0;i < 27;i++, inc(u, 3)){
					for(int j = 0;j < 3;j++){
						if(u[j] == j ){
							for(int k = 0;k < 3;k++){
								if(iord[j*3+2] > iord[k*3])continue outer;
							}
							for(int k = j+1;k < 3;k++){
								if(iord[j*3+2] > iord[k*3+1])continue outer;
							}
						}
					}
					boolean[] lifted = new boolean[3];
					boolean[] lift = new boolean[3];
					for(int j = 0;j < 9;j++){
						int me = ord[j]/3;
						int targ = u[ord[j]/3];
						if(lifted[me])continue outer;
						if(ord[j] % 3 == 0 && lift[me])continue outer;
						if(ord[j] % 3 == 1 && targ != me){
							if(lifted[targ])continue outer;
							lifted[targ] = true;
							lift[me] = true;
						}
						if(ord[j] % 3 == 2 && targ != me){
							if(!lifted[targ])continue outer;
							lifted[targ] = false;
							lift[me] = false;
						}
					}

					for(int j = 0;j < 3;j++){
						s[j][3] = s[j][0];
					}
					gmax = Math.max(gmax, rec(ord, u, 0, s, 0, 0));
					ct++;
//					if(ct % 100 == 0)tr(ct);
				}
			}
		}while(nextPermutation(iord));
//		tr(ct);
		out.println(gmax);
	}

	int gmax;
	boolean invalid(int[] ord, int[] u, int pos, int[][] s)
	{
		int[] ss = new int[3];
		for(int i = 0;i < 3;i++){
			ss[i] = s[i][3];
		}
		for(int i = pos;i < 9;i++){
			int me = ord[i]/3;
			int targ = u[ord[i]/3];
			int com = ord[i] % 3;
			if(com == 0){
				ss[me] += s[me][1];
			}else if(com == 1 && me != targ){
				for(int j = 0;j < 3;j++){
					if(me != j)ss[j]++;
				}
			}else if(com == 2 && me != targ){
				for(int j = 0;j < 3;j++){
					if(me != j)ss[j] += s[me][2];
				}
			}
		}

		int mx = Math.max(Math.max(ss[0], ss[1]), ss[2]);
		return mx <= gmax;
	}

	int rec(int[] ord, int[] u, int pos, int[][] s, int lift, int lifted)
	{
		if(pos == 9){
			return Math.max(Math.max(s[0][3], s[1][3]), s[2][3]);
		}
		if(invalid(ord, u, pos, s))return 0;

		int me = ord[pos]/3;
		int targ = u[ord[pos]/3];
		int com = ord[pos]%3;
		int max = 0;
		if(com == 0){
			outer:
			for(int i = s[me][1];i >= -s[me][1];i--){
				for(int j = 0;j < 3;j++){
					if(me != j && s[me][3] + i == s[j][3])continue outer;
				}
				s[me][3] += i;
				max = Math.max(max, rec(ord, u, pos+1, s, lift, lifted));
				s[me][3] -= i;
//				if(pos == 8)break;
			}
		}else if(com == 1){
			if(me == targ){
				max = Math.max(max, rec(ord, u, pos+1, s, lift, lifted));
			}else{
				if(Math.abs(s[me][3] - s[targ][3]) == 1){
					lift ^= 1<<me;
					lifted ^= 1<<targ;
					int o = s[targ][3];
					s[targ][3] = s[me][3];
					if(lift<<31-targ<0){
						int other = Integer.numberOfTrailingZeros(7-(1<<me)-(1<<targ));
						s[other][3] = s[me][3];
					}
					max = Math.max(max, rec(ord, u, pos+1, s, lift, lifted));
					s[targ][3] = o;
					if(lift<<31-targ<0){
						int other = Integer.numberOfTrailingZeros(7-(1<<me)-(1<<targ));
						s[other][3] = s[targ][3];
					}
					lift ^= 1<<me;
					lifted ^= 1<<targ;
				}
			}
		}else if(com == 2){
			if(me == targ){
				max = Math.max(max, rec(ord, u, pos+1, s, lift, lifted));
			}else{
				outer2:
				for(int i = s[me][2];i >= -s[me][2];i--){
					for(int j = 0;j < 3;j++){
						if(s[targ][3] + i == s[j][3])continue outer2;
					}
					int o = s[targ][3];
					s[targ][3] = s[me][3] + i;
					if(lift<<31-targ<0){
						int other = Integer.numberOfTrailingZeros(7-(1<<me)-(1<<targ));
						s[other][3] = s[targ][3];
					}
					lifted ^= 1<<targ;
					lift ^= 1<<me;
					max = Math.max(max, rec(ord, u, pos+1, s, lift, lifted));
					lifted ^= 1<<targ;
					lift ^= 1<<me;
					s[targ][3] = o;
					if(lift<<31-targ<0){
						int other = Integer.numberOfTrailingZeros(7-(1<<me)-(1<<targ));
						s[other][3] = s[targ][3];
					}
//					if(pos == 8)break;
				}
			}
		}
		return max;
	}

	public static boolean inc(int[] a, int base)
	{
		int n = a.length;
		int i;
		for(i = n - 1;i >= 0 && a[i] == base - 1;i--);
		if(i == -1)return false;

		a[i]++;
		Arrays.fill(a, i + 1, n, 0);
		return true;
	}

	public static boolean nextPermutation(int[] src)
	{
		int i;
		for(i = src.length - 2;i >= 0 && src[i] > src[i+1];i--);
		if(i == -1)return false;
		int j;
		for(j = i + 1;j < src.length && src[i] < src[j];j++);
		int d = src[i]; src[i] = src[j - 1]; src[j - 1] = d;
		for(int p = i + 1, q = src.length - 1;p < q;p++,q--){
			d = src[p]; src[p] = src[q]; src[q] = d;
		}
		return true;
	}

	void run() throws Exception
	{
		in = oj ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

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

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

	int ni() { return Integer.parseInt(in.next()); }
	long nl() { return Long.parseLong(in.next()); }
	double nd() { return Double.parseDouble(in.next()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


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

public final class barels_and_boxes
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static Random rnd=new Random();
	static long[] fact,inv_fact;
	static int maxn=(int)(2e5+5);
	static long mod=(long)(1e9+7);

	static int add(long a,long b)
	{
		long ret=a+b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static int mul(long a,long b)
	{
		long ret=a*b;

		if(ret>=mod)
		{
			ret%=mod;
		}

		return (int)ret;
	}

	static long pow(long a,long b)
	{
		long x=1,y=a;

		while(b>0)
		{
			if(b%2==1)
			{
				x=(x*y)%mod;
			}

			y=(y*y)%mod;b=b/2;
		}

		return x;
	}

	static void build()
	{
		fact=new long[maxn];inv_fact=new long[maxn];fact[0]=1;

		for(int i=1;i<maxn;i++)
		{
			fact[i]=(fact[i-1]*i)%mod;
		}

		inv_fact[maxn-1]=pow(fact[maxn-1],mod-2);

		for(int i=maxn-2;i>=0;i--)
		{
			inv_fact[i]=(inv_fact[i+1]*(i+1))%mod;
		}
	}

	static long C(int n,int r)
	{
		if(n-r<0 || Math.min(n,r)<0)
		{
			return 0;
		}

		long val1=fact[n],val2=inv_fact[r],val3=inv_fact[n-r];

		long mul=(val2*val3)%mod;

		return (val1*mul)%mod;
	}

	static long get(long tot,int nums,int flag)
	{
		if(nums==0)
		{
			return (tot==0?1:0);
		}

		else
		{
			if(flag==1)
			{
				return C((int)(tot-1),nums-1);
			}

			else
			{
				return C((int)tot+nums-1,nums-1);
			}
		}
	}

    public static void main(String args[]) throws Exception
    {
		build();

		int f=sc.nextInt(),w=sc.nextInt(),h=sc.nextInt();

		long p=0,q=0;

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long val1=C(f-1,i-1),val2=C(w-1,i-1);

			long zz=mul(val1,val2);

			zz=mul(zz,2);

			q=add(q,zz);

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long val1=C(f-1,i-1),val2=get(w,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long val1=C(w-1,i-1),val2=get(f,i-1,1);

				long zz=mul(val1,val2);

				q=add(q,zz);
			}
		}

		for(int i=1;i<=Math.min(f,w);i++)
		{
			long now=(w*1L)-((i*1L*(h+1)));

			if(now>=0)
			{
				long val1=C(f-1,i-1),val2=get(now,i,-1);

				long zz=mul(val1,val2);

				zz=mul(zz,2);

				p=add(p,zz);
			}

		}

		for(int i=1;i<=f;i++)
		{
			if(w>=i-1)
			{
				long now=(w*1L)-((i-1)*1L*(h+1));

				if(now>=0)
				{
					long val1=C(f-1,i-1),val2=get(now,i-1,-1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		for(int i=1;i<=w;i++)
		{
			if(f>=i-1)
			{
				long now=(w*1L)-(i*1L*(h+1));

				if(now>=0)
				{
					long val1=get(now,i,-1),val2=get(f,i-1,1);

					long zz=mul(val1,val2);

					p=add(p,zz);
				}
			}
		}

		long den=pow(q,mod-2),res=mul(p,den);

		out.println(res);out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

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

	public String next() throws Exception {
		return nextToken().toString();
	}

    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.util.Scanner;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner read = new Scanner(System.in);
        int cm = read.nextInt();
        // 1 in = 3 cm
        // 1 fo = 12 inc
        // 1/36 fo = 1 cm
        //1 fo = 36 cm
        int feet , inch;
        feet = cm / 36;
        inch = (cm % 36) / 3;
        inch += ((cm % 36) % 3)>1?1:0;
        feet += (inch / 12);
        inch = inch % 12;
        System.out.printf("%d %d\n", feet, inch);
    }

}


import java.util.Scanner;

public class A1043
{
    public static void main(String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int opponentVotes = 0;
        int max = Integer.MIN_VALUE;
        int[] votes = new int[n];
        for (int i = 0; i < n; i++)
        {

            votes[i] = scanner.nextInt();
            if(votes[i] > max)
                max = votes[i];
            opponentVotes += votes[i];
        }
        int myMax = max;

        while(func(myMax, votes) <= opponentVotes)
            myMax++;
        System.out.println(myMax);

    }

    private static int func(int myMax, int[] votes)
    {
        int  sum = 0;
        for (int vote : votes)
        {
            sum = sum + myMax - vote;
        }
        return sum;
    }
}


import java.util.*;
public class ProE {
	static long aa,bb,cc,dd,a,b,c,d,ans;

	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		a=in.nextInt();b=in.nextInt();
		c=in.nextInt();d=in.nextInt();
		aa=(c-a+1)/2+1;bb=(c-a+1)/2;
		cc=(d-b+1)/2+1;dd=(d-b+1)/2;
		ans=aa*cc+bb*dd;
		System.out.println(ans);
	}
}


// practice with rainboy
import java.io.*;
import java.util.*;

public class CF445D {
	static int x;
	static int getNextX() {
		x = (int) ((x * 37L + 10007) % 1000000007);
		return x;
	}
	static int[] aa, bb;
	static void initAB(int n, int d) {
		aa = new int[n];
		bb = new int[n];
		for (int i = 0; i < n; i++)
			aa[i] = i + 1;
		for (int i = 0; i < n; i++) {
			int j = getNextX() % (i + 1);
			int tmp = aa[i]; aa[i] = aa[j]; aa[j] = tmp;
		}
		for (int i = 0; i < n; i++)
			bb[i] = i < d ? 1 : 0;
		for (int i = 0; i < n; i++) {
			int j = getNextX() % (i + 1);
			int tmp = bb[i]; bb[i] = bb[j]; bb[j] = tmp;
		}
	}
	static final int S = 20;
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(System.out);
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int d = Integer.parseInt(st.nextToken());
		x = Integer.parseInt(st.nextToken());
		initAB(n, d);
		int[] ii = new int[S + 1];
		int[] jj = new int[n];
		int k = 0;
		for (int i = 0; i < n; i++) {
			int h = i < S ? i : S;
			while (h > 0 && aa[ii[h - 1]] < aa[i]) {
				ii[h] = ii[h - 1];
				h--;
			}
			ii[h] = i;
			if (bb[i] == 1)
				jj[k++] = i;
			int c = 0;
			for (h = 0; h <= i && h < S; h++)
				if (bb[i - ii[h]] == 1) {
					c = aa[ii[h]];
					break;
				}
			if (c == 0)
				for (h = 0; h < k; h++)
					c = Math.max(c, aa[i - jj[h]]);
			pw.println(c);
		}
		pw.close();
	}
}


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

public class D {

	static final long mod = 1000000007;

	static class Doit{
		public void solve(int testNumber, InputReader in, PrintWriter out) {

			int n = Integer.parseInt(in.next());
			int k = Integer.parseInt(in.next());

			Set<String> set = new HashSet<>();
			Queue<String> current = new ArrayDeque<>();
			current.add(in.next());

			int cant = 1;
			int sum = 0;

			String sub, st = "";

			while(!current.isEmpty() && cant < k) {

				st = current.remove();

				for(int j = 0; j < st.length(); j++) {
					sub = ((st.length() == 1)? "" : st.substring(0, j) + st.substring(j + 1));
					if(!set.contains(sub)) {
						//System.out.println(sub);
						set.add(sub);
						current.add(sub);
						cant++;
						sum += n - sub.length() ;
						if(k == cant)break;
					}
				}
			}

			if(cant < k) {
				System.out.println(-1);
			}else {
				System.out.println(sum);
			}

		}
	}

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

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

	}
}


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

public class Busters {
    public static void main(String[] args) throws IOException {
        BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        StringTokenizer st = new StringTokenizer(rd.readLine());
        a = Integer.parseInt(st.nextToken());
        b = Integer.parseInt(st.nextToken());
        w = Integer.parseInt(st.nextToken());
        x = Integer.parseInt(st.nextToken());
        c = Integer.parseInt(st.nextToken());
        countPeriods();
        System.out.println(bin(0, Long.MAX_VALUE/1000));
    }

    static long bin(long a, long b){
        if(a==b) return a;
        if(b==a+1) return check(a) ? a : b;
        long m = (a+b)/2;
        return check(m) ? bin(a, m) : bin(m+1, b);
    }

    static boolean check(long X){
        long A = a - count(X), C = c-X;
        return C <= A;
    }

    static long count(long X){
        if(X<=P) return simulation((int)X);
        long res = 1L*S*(X/P);
        return res + count(X % P);
    }

    static int simulation(int X){
        int num = 0;
        int B = b;
        for(int i=0; i<X; i++){
            if(B>=x){
                B -= x;
            }
            else{
                B -= x;
                B += w;
                num++;
            }
        }
        return num;
    }

    static void countPeriods(){
        int curB = b;
        boolean first = true;
        while(true){
            if(curB==b && !first) break;
            first = false;
            if(curB >= x){
                curB -= x;
                P++;
            }
            else{
                P++;
                S++;
                curB -= x;
                curB += w;
            }
        }
    }

    static int P, S;

    static int a, b, w, x, c;

}


import java.util.*;

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

public class tr0 {
	static StringBuilder sb;
	static int inf = (int) 1e9;
	static int mod = 998244353;
	static int n, m, k;
	static ArrayList<Integer>[] ad;
	static long[] f, inv, memo[];
	static PrintWriter out;

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		n = sc.nextInt();
		k = sc.nextInt();
		memo = new long[n + 5][k + 5];
		f = new long[n + 4];
		inv = new long[n + 4];
		f[0] = 1;
		inv[0] = 1;
		for (int i = 1; i < f.length; i++) {
			f[i] = (i * f[i - 1]) % mod;
			inv[i] = modPow(f[i], mod - 2);
		}
		for (long[] a : memo)
			Arrays.fill(a, -1);
		out.println(dp(0, 1));
		out.flush();
	}

	static long dp(int i, int ck) {
		if (i == n - 1)
			return f[n - 1];
		if (ck > k)
			return 0;

		if (memo[i][ck] != -1)
			return memo[i][ck];
		long ans = dp(i, ck + 1);
		for (int j = 1; true; j++) {
			if (i + j > n - 1)
				break;
			long tem = (dp(i + j, ck + 1) * inv[j]) % mod;
			tem = (tem * modPow(k - ck + 1, (j * (j - 1) / 2) + j * i)) % mod;
			ans += tem;
			ans %= mod;
		}
		return memo[i][ck] = ans;
	}

	static long modPow(long a, long e)

	{
		long res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	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 int[] nextArrInt(int n) throws IOException {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

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

		public int[] nextArrIntSorted(int n) throws IOException {
			int[] a = new int[n];
			Integer[] a1 = new Integer[n];
			for (int i = 0; i < n; i++)
				a1[i] = nextInt();
			Arrays.sort(a1);
			for (int i = 0; i < n; i++)
				a[i] = a1[i].intValue();
			return a;
		}

		public long[] nextArrLongSorted(int n) throws IOException {
			long[] a = new long[n];
			Long[] a1 = new Long[n];
			for (int i = 0; i < n; i++)
				a1[i] = nextLong();
			Arrays.sort(a1);
			for (int i = 0; i < n; i++)
				a[i] = a1[i].longValue();
			return a;
		}

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

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.System.exit;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

public class C {

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

	static class Request {
		final int pin1, left1, right1, pin2, left2, right2;

		static final Map<Request, Integer> cache = new HashMap<Request, Integer>();

		Request(int pin1, int left1, int right1, int pin2, int left2,
				int right2) {
			if (pin1 < pin2) {
				int t = pin1;
				pin1 = pin2;
				pin2 = t;
				t = left1;
				left1 = left2;
				left2 = t;
				t = right1;
				right1 = right2;
				right2 = t;
			}
			this.pin1 = pin1;
			this.left1 = left1;
			this.right1 = right1;
			this.pin2 = pin2;
			this.left2 = left2;
			this.right2 = right2;
		}

		Request(int l1, int r1, int l2, int r2) {
			this(pin(l1, r1), left(l1, r1), right(l1, r1), pin(l2, r2), left(l2, r2), right(l2, r2));
		}

		static int pin(int l, int r) {
			int pin = -1;
			while (l <= r) {
				pin = Integer.numberOfTrailingZeros(l);
				l = (l | (l - 1)) + 1;
			}
			return pin;
		}

		static int left(int l, int r) {
			int pin = pin(l, r);
			int pinMask = (1 << pin) - 1;
			int pinPos = (l + pinMask) & ~pinMask;
			return pinPos - l;
		}

		static int right(int l, int r) {
			int pin = pin(l, r);
			int pinMask = (1 << pin) - 1;
			int pinPos = (l + pinMask) & ~pinMask;
			return r - pinPos;
		}

		int getAns() {
			Integer ans = cache.get(this);
			if (ans != null) {
				return ans;
			}
			ans = doGetAns();
			cache.put(this, ans);
			return ans;
		}

		int doGetAns() {
			int cans = 0;
			if (pin1 == pin2) {
				cans = 1 + min(left1, left2) + min(right1, right2);
			}
			if (left1 > 0) {
				cans = max(cans, new Request(-left1, -1, (1 << pin2) - left2, (1 << pin2) + right2).getAns());
			}
			if (right1 > 0) {
				cans = max(cans, new Request(1, right1, (1 << pin2) - left2, (1 << pin2) + right2).getAns());
			}
			return cans;
		}

		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + left1;
			result = prime * result + left2;
			result = prime * result + pin1;
			result = prime * result + pin2;
			result = prime * result + right1;
			result = prime * result + right2;
			return result;
		}

		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Request other = (Request) obj;
			if (left1 != other.left1)
				return false;
			if (left2 != other.left2)
				return false;
			if (pin1 != other.pin1)
				return false;
			if (pin2 != other.pin2)
				return false;
			if (right1 != other.right1)
				return false;
			if (right2 != other.right2)
				return false;
			return true;
		}
	}

	static void solve() throws Exception {
		out.print(new Request(nextInt(), nextInt(), nextInt(), nextInt()).getAns());
	}

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

	static long nextLong() throws IOException {
		return parseLong(next());
	}

	static double nextDouble() throws IOException {
		return parseDouble(next());
	}

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

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


import java.util.Scanner;
import java.util.*;
import java.lang.*;
import java.util.regex.Pattern;
import java.text.DecimalFormat;
import java.util.stream.IntStream;
public class Main{
public static void main(String[] args)
{     Scanner scanner=new Scanner(System.in);
      String w1=scanner.next();
      String w2=scanner.next();
      String l1[] = w1.split(":");
      String l2[] = w2.split(":");
      int h1= Integer.parseInt(l1[0]);
      int m1= Integer.parseInt(l1[1]);
      int h2= Integer.parseInt(l2[0]);
      int m2= Integer.parseInt(l2[1]);
      int mi=h1*60+m1;
      int mf=h2*60+m2;
      int mid=(mf-mi)/2;
      int ans1=h1+(mid)/60;
      int ans2=m1+(mid)%60;
      if(ans2>=60)
            {ans1++;
             ans2=ans2%60;}
      if(ans1<10)
            System.out.print("0"+ans1);
      else System.out.print(ans1);
      System.out.print(":");
      if(ans2<10)
            System.out.print("0"+ans2);
      else System.out.print(ans2);
 }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
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) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            FTheSumOfTheKThPowers solver = new FTheSumOfTheKThPowers();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class FTheSumOfTheKThPowers {
        public void solve(int testNumber, FastInput in, FastOutput out) {
            int mod = (int) (1e9 + 7);
            int n = in.readInt();
            int k = in.readInt();

            if (k == 0) {
                out.println(n);
                return;
            }

            Power power = new Power(mod);
            int[] y = new int[k + 2];
            for (int i = 0; i <= k + 1; i++) {
                y[i] = power.pow(i, k);
            }
            for (int i = 1; i <= k + 1; i++) {
                y[i] = DigitUtils.modplus(y[i - 1], y[i], mod);
            }

            ModContinuousInterpolation interpolation = new ModContinuousInterpolation(0, y, mod);

            int ans = interpolation.interpolate(n);
            out.println(ans);
        }

    }

    static interface InverseNumber {
    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private StringBuilder cache = new StringBuilder(10 << 20);
        private final Writer os;

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            return this;
        }

        public FastOutput println(int c) {
            return append(c).println();
        }

        public FastOutput println() {
            cache.append(System.lineSeparator());
            return this;
        }

        public FastOutput flush() {
            try {
                os.append(cache);
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int negate(int x, int mod) {
            return x == 0 ? 0 : mod - x;
        }

        public static int modsub(int a, int b, int mod) {
            int ans = a - b;
            if (ans < 0) {
                ans += mod;
            }
            return ans;
        }

        public static int modplus(int a, int b, int mod) {
            int ans = a + b;
            if (ans >= mod) {
                ans -= mod;
            }
            return ans;
        }

    }

    static class Power implements InverseNumber {
        int mod;

        public Power(Modular modular) {
            this.mod = modular.getMod();
        }

        public Power(int mod) {
            this(new Modular(mod));
        }

        public int pow(int x, int n) {
            if (n == 0) {
                return 1 % mod;
            }
            long r = pow(x, n >> 1);
            r = r * r % mod;
            if ((n & 1) == 1) {
                r = r * x % mod;
            }
            return (int) r;
        }

    }

    static class Modular {
        int m;

        public int getMod() {
            return m;
        }

        public Modular(int m) {
            this.m = m;
        }

        public Modular(long m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public Modular(double m) {
            this.m = (int) m;
            if (this.m != m) {
                throw new IllegalArgumentException();
            }
        }

        public String toString() {
            return "mod " + m;
        }

    }

    static class Factorial {
        int[] fact;
        int[] inv;
        int mod;

        public Factorial(int[] fact, int[] inv, int mod) {
            this.mod = mod;
            this.fact = fact;
            this.inv = inv;
            fact[0] = inv[0] = 1;
            int n = Math.min(fact.length, mod);
            for (int i = 1; i < n; i++) {
                fact[i] = i;
                fact[i] = (int) ((long) fact[i] * fact[i - 1] % mod);
            }
            inv[n - 1] = BigInteger.valueOf(fact[n - 1]).modInverse(BigInteger.valueOf(mod)).intValue();
            for (int i = n - 2; i >= 1; i--) {
                inv[i] = (int) ((long) inv[i + 1] * (i + 1) % mod);
            }
        }

        public Factorial(int limit, int mod) {
            this(new int[limit + 1], new int[limit + 1], mod);
        }

        public int invFact(int n) {
            return inv[n];
        }

    }

    static class ModContinuousInterpolation {
        private int x0;
        private int[] y;
        private int mod;
        private int[] pre;
        private int[] post;
        private Factorial fact;

        public ModContinuousInterpolation(int x0, int[] y, int mod) {
            this(x0, y, mod, new Factorial(y.length - 1, mod));
        }

        public ModContinuousInterpolation(int x0, int[] y, int mod, Factorial fact) {
            this.x0 = x0;
            this.y = y;
            this.mod = mod;

            int n = y.length;
            pre = new int[n];
            post = new int[n];
            this.fact = fact;
        }

        public int interpolate(int x) {
            x = DigitUtils.modsub(x, x0, mod);
            int n = y.length;
            if (x < n) {
                return y[x];
            }

            for (int i = 0; i < n; i++) {
                pre[i] = post[i] = DigitUtils.modsub(x, i, mod);
            }
            for (int i = 1; i < n; i++) {
                pre[i] = (int) ((long) pre[i - 1] * pre[i] % mod);
                post[n - i - 1] = (int) ((long) post[n - i - 1] * post[n - i] % mod);
            }

            long sum = 0;
            for (int i = 0; i < n; i++) {
                int local = (int) ((long) y[i] * fact.invFact(i) % mod * fact.invFact(n - 1 - i) % mod);
                if (i > 0) {
                    local = (int) ((long) local * pre[i - 1] % mod);
                }
                if (i + 1 < n) {
                    local = (int) ((long) local * post[i + 1] % mod);
                }
                if (((n - 1 - i) & 1) == 1) {
                    local = DigitUtils.negate(local, mod);
                }
                sum += local;
            }

            return (int) (sum % mod);
        }

    }
}


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.List;

public class Main {

	private static final String NO = "NO";
	private static final String YES = "YES";
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	private static final long MOD = 1000000007;
	private static final long inf = 100000000000L;
	private static final int max_coord = 50;

	void solve() {
		int T = 1;
		for (int i = 0; i < T; i++)
			solve(i);
	}

	int n;

	void solve(int T) {
		n = ni();
		int a[][] = na(2, 2);
		if (a[0][0] == a[1][0]) {
			out.println(YES);
			return;
		}
		for (; a[0][0] != a[0][1] && a[1][0] != a[1][1];) {
			a[0][0]++;
			if (a[0][0] > n)
				a[0][0] = 1;
			a[1][0]--;
			if (a[1][0] <= 0)
				a[1][0] = n;
			if (a[0][0] == a[1][0]) {
				out.println(YES);
				return;
			}
		}
		out.println(NO);
	}

	// a^b
	long power(long a, long b) {
		long x = 1, y = a;
		while (b > 0) {
			if (b % 2 != 0) {
				x = (x * y) % MOD;
			}
			y = (y * y) % MOD;
			b /= 2;
		}
		return x % MOD;
	}

	private long gcd(long a, long b) {
		while (a != 0) {
			long tmp = b % a;
			b = a;
			a = tmp;
		}
		return b;
	}

	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 Main().run();
	}

	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	private boolean vis[];

	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) {
			if (!(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 List<Integer> na2(int n) {
		List<Integer> a = new ArrayList<Integer>();
		for (int i = 0; i < n; i++)
			a.add(ni());
		return a;
	}

	private int[][] na(int n, int m) {
		int[][] a = new int[n][];
		for (int i = 0; i < n; i++)
			a[i] = na(m);
		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(int n) {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nl();
		return a;
	}

	private long[][] nl(int n, int m) {
		long[][] a = new long[n][];
		for (int i = 0; i < n; i++)
			a[i] = nl(m);
		return a;
	}

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

	public class Pair<K, V> {

		/**
		 * Key of this Pair.
		 */
		private K key;

		/**
		 * Gets the key for this pair.
		 *
		 * @return key for this pair
		 */
		public K getKey() {
			return key;
		}

		/**
		 * Value of this this Pair.
		 */
		private V value;

		/**
		 * Gets the value for this pair.
		 *
		 * @return value for this pair
		 */
		public V getValue() {
			return value;
		}

		/**
		 * Creates a new pair
		 *
		 * @param key   The key for this pair
		 * @param value The value to use for this pair
		 */
		public Pair(K key, V value) {
			this.key = key;
			this.value = value;
		}

		/**
		 *

		 * String representation of this Pair.
		 *

		 *
		 *

		 * The default name/value delimiter '=' is always used.
		 *

		 *
		 * @return String representation of this Pair
		 */
		@Override
		public String toString() {
			return key + "=" + value;
		}

		/**
		 *

		 * Generate a hash code for this Pair.
		 *

		 *
		 *

		 * The hash code is calculated using both the name and the value of the
		 * Pair.
		 *

		 *
		 * @return hash code for this Pair
		 */
		@Override
		public int hashCode() {
			// name's hashCode is multiplied by an arbitrary prime number (13)
			// in order to make sure there is a difference in the hashCode between
			// these two parameters:
			// name: a value: aa
			// name: aa value: a
			return key.hashCode() * 13 + (value == null ? 0 : value.hashCode());
		}

		/**
		 *

		 * Test this Pair for equality with another Object.
		 *

		 *
		 *

		 * If the Object to be tested is not a Pair or is
		 * null, then this method returns false.
		 *

		 *
		 *

		 * Two Pairs are considered equal if and only if both the names and
		 * values are equal.
		 *

		 *
		 * @param o the Object to test for equality with this
		 *          Pair
		 * @return true if the given Object is equal to this
		 *         Pair else false
		 */
		@Override
		public boolean equals(Object o) {
			if (this == o)
				return true;
			if (o instanceof Pair) {
				Pair pair = (Pair) o;
				if (key != null ? !key.equals(pair.key) : pair.key != null)
					return false;
				if (value != null ? !value.equals(pair.value) : pair.value != null)
					return false;
				return true;
			}
			return false;
		}
	}

}


import java.util.Scanner;

public class Sum {

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

        String v1 = sc.next();
        String v2 = sc.next();

        int max = 0;
        max = getMaxDigit(v1);
        max = max > getMaxDigit(v2) ? max : getMaxDigit(v2) ;

        int base = max +1;
//      System.out.println(base);

        int number1 = Integer.parseInt(v1, base);
        int number2 = Integer.parseInt(v2, base);

        int sum = number1 + number2;
        System.out.println(Integer.toString(sum, base).length());

    }

    private static int getMaxDigit(String number) {

        int max =0;

        for(int i =0 ; i< number.length(); i++){
            int v = number.charAt(i) - '0' ;
            if(v > max) max = v;
        }
        return max;
    }

}


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.PrintWriter;
import java.util.Arrays;
import java.util.StringTokenizer;
import java.util.TreeSet;
/*
 * Java Input / Output Class using Buffered/ Input Straem
 * Created by @neelbhallabos
 * File Created at: Mar 25, 2019
 */
public class BrickEnumeration {
	public static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
	public static StringTokenizer st;
	public static PrintWriter pw = new PrintWriter(System.out);
	final static boolean debugmode = true;
	public static int k = 7; // for 10^9 + k mods.
	public static long STMOD = 1000000000 + k; // 10^9 + k

	public static void main(String[] args) throws IOException {
		int nbricks = getInt();
		int paintbuckets = getInt();
		int numtransitions = getInt();
		long[][] dp = new long[nbricks][numtransitions + 1];
		dp[0][0] = paintbuckets; // the first brick will have 0 transitions
		for(int cbrick = 1; cbrick < nbricks;cbrick++) {
			// handle the no transition case prior.
			dp[cbrick][0] = dp[cbrick-1][0];
			for(int ctransition = 1; ctransition <numtransitions + 1;ctransition++) {

					dp[cbrick][ctransition] = dp[cbrick-1][ctransition];
					dp[cbrick][ctransition] %= 998244353;
					dp[cbrick][ctransition] += dp[cbrick-1][ctransition -1] * (paintbuckets-1);
					dp[cbrick][ctransition] %= 998244353;

			}
		}

		submit(dp[dp.length-1][numtransitions],true);
	}
	public static int nchoosekmod(int n, int k, int mod) {
		//(n!)/ (n-k)! k!
		int res = 1;

        // Since C(n, k) = C(n, n-k)
        if ( k > n - k )
            k = n - k;

        // Calculate value of [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
        for (int i = 0; i < k; ++i)
        {
        res *= (n - i);
        res /= (i + 1);
        res %= mod;

        }

        return res;

	}
	public static void setInputFile(String fn) throws IOException {
		sc = new BufferedReader(new FileReader(fn));
	}

	public static void setOutputFile(String fn) throws IOException {
		pw = new PrintWriter(new BufferedWriter(new FileWriter(fn)));
	}

	public static int GCD(int a, int b) {
		if (b == 0)
			return a;
		return GCD(b, a % b);
	}

	public static double log(int k, int v) {
		return Math.log(k) / Math.log(v);
	}

	public static long longpower(int a, int b) {
		long[] vals = new long[(int) (log(b, 2) + 2)];
		vals[0] = a;
		vals[1] = a * a;
		for (int i = 1; i < vals.length; i++) {
			vals[i] = vals[i - 1] * vals[i - 1];
		}
		long ans = 1;
		int cindex = 0;
		while (b != 0) {
			if (b % 2 == 1) {
				ans *= vals[cindex];
			}
			cindex += 1;
			b /= 2;
		}
		return ans;

	}

	public static void debug(String toPrint) {
		if (!debugmode) {
			return;
		}
		pw.println("[DEBUG]: " + toPrint);
	}

	public static void submit(int[] k, boolean close) {
		pw.println(Arrays.toString(k));
		if (close) {
			pw.close();
		}
	}

	public static void submit(int p, boolean close) {
		pw.println(Integer.toString(p));
		if (close) {
			pw.close();
		}
	}

	public static void submit(String k, boolean close) {
		pw.println(k);
		if (close) {
			pw.close();
		}
	}

	public static void submit(double u, boolean close) {
		pw.println(Double.toString(u));
		if (close) {
			pw.close();
		}
	}

	public static void submit(long lng, boolean close) {
		pw.println(Long.toString(lng));
		if (close) {
			pw.close();
		}

	}

	public static void submit() {
		pw.close();
	}

	public static int getInt() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Integer.parseInt(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Integer.parseInt(st.nextToken());
	}

	public static long getLong() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Long.parseLong(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Long.parseLong(st.nextToken());
	}

	public static double getDouble() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Double.parseDouble(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Double.parseDouble(st.nextToken());
	}

	public static String getString() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return st.nextToken();
		}
		st = new StringTokenizer(sc.readLine());
		return st.nextToken();
	}

	public static String getLine() throws IOException {
		return sc.readLine();
	}

	public static int[][] readMatrix(int lines, int cols) throws IOException {
		int[][] matrr = new int[lines][cols];
		for (int i = 0; i < lines; i++) {
			for (int j = 0; j < cols; j++) {
				matrr[i][j] = getInt();
			}
		}
		return matrr;
	}

	public static int[] readArray(int lines) throws IOException {
		int[] ar = new int[lines];
		for (int i = 0; i < lines; i++)
			ar[i] = getInt();
		return ar;
	}

}
/*

public class BrickEnumeration {

}

*/


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

public class Main {
    private static final BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    private static StringTokenizer st = new StringTokenizer("");

    public static void main(String[] args) {
        int k = ni();
        int p = ni();
        long sum = 0;
        for (int i = 1; i <= k; i++) {
            String s = Long.toString(i);
            sum = (sum + Long.parseLong(s + new StringBuilder(s).reverse())) % p;
        }
        System.out.println(sum);
    }

    private static String ns() {
        while (!st.hasMoreTokens()) try {
            st = new StringTokenizer(br.readLine());
        } catch (IOException ignored) {
        }
        return st.nextToken();
    }

    private static int ni() {
        return Integer.parseInt(ns());
    }

    private static long nl() {
        return Long.parseLong(ns());
    }
}