#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void){

    int n, *hs;
    long *costs;
    scanf("%d\n", &n);

    const int k = 2;

    hs = malloc(n * sizeof(int));
    costs = malloc(n * sizeof(long));

    for(int c = getchar(), i = 0; i < n; c = getchar(), ++i){

        while(isspace(c)) c = getchar();
        int val = 0;
        for(; c >= '0'; c = getchar()) val = val * 10 + c - '0';
        hs[i] = val;
    }

    costs[0] = 0;
    int lim = k < n ? k : n;
    for(int i = 1; i < lim; ++i){

        int hi = hs[i];
        long min = LONG_MAX;
        for(int j = 0; j < i; ++j){

            int testing = costs[j] + abs(hi - hs[j]);
            if(testing < min) min = testing;
        }
        costs[i] = min;
    }

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

        int hi = hs[i];
        long min = LONG_MAX;
        for(int j = i - k; j < i; ++j){

            int testing = costs[j] + abs(hi - hs[j]);
            if(testing < min) min = testing;
        }
        costs[i] = min;
    }

    printf("%li", costs[n - 1]);
}


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h> // uint64_t

#define NUM_MAX 100000
#define BUF_SIZE (NUM_MAX*7+50)

int get_int(void) {
  int num;
#ifdef BUF_SIZE
  char line[BUF_SIZE];
  if(!fgets(line, BUF_SIZE, stdin)) return 0;
  sscanf(line, "%d", &num);
#else
#error
#endif
  return num;
}

// <arr[0]> <arr[1]> .. <arr[size-1]>
int fget_array(int *arr, int size) {
#ifdef BUF_SIZE
    char line[BUF_SIZE];
    char *tmpbuf = line;
    int i;
    if(!fgets(line, BUF_SIZE, stdin)) return -1;
    for(i = 0; i < size; i++) {
        char *tmp = strtok(tmpbuf, " ");
        arr[i] = strtol(tmp, NULL, 10);
        tmpbuf = NULL;
    }
#else
#error
#endif
    return 0;
}

#define min(a,b) ((a) > (b) ? (b) : (a))

int main(void) {
    int num = get_int();
    static int arr[NUM_MAX+1];
    static int dp[NUM_MAX+1];
    memset(dp, 0x3f, sizeof(int)*(NUM_MAX+1));
    fget_array(&arr[1], num);
    int i;
    dp[1] = 0;
    dp[2] = dp[1] + abs(arr[2] - arr[1]);
    for(i = 3; i <= num; i++) {
        dp[i] = min(dp[i], dp[i-1] + abs(arr[i]-arr[i-1]));
        dp[i] = min(dp[i], dp[i-2] + abs(arr[i]-arr[i-2]));
    }
    printf("%d\n", dp[num]);
    return 0;
}


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <functional>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define MOD 1000000007
#define MOD9 1000000009
#define pi 3.1415926535
#define ms(s, n) memset(s, n, sizeof(s))
#define prec(n) fixed<<setprecision(n)
#define eps 0.000001
#define all(v) v.begin(), v.end()
#define allr(v) v.rbegin(), v.rend()
#define fast ios::sync_with_stdio(0);cin.tie(NULL);cout.tie(NULL)
#define umll unordered_map<ll,ll>
#define mll map<ll,ll>
#define forr(i,p,n) for(ll i=p;i<(ll)n;i++)
#define fore(i,n,k) for(ll i=n-1;i>=k;i--)
#define MAXN 1000003
typedef long long ll;
using namespace std;
ll mult(ll a, ll b, ll p = MOD) {return ((a % p) * (b % p)) % p;}
ll add(ll a, ll b, ll p = MOD) {return (a % p + b % p) % p;}
ll fpow(ll n, ll k, ll p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
ll inv(ll a, ll p = MOD) {return fpow(a, p - 2, p);}
ll inv_euclid(ll a, ll m = MOD) {ll m0 = m; ll y = 0, x = 1; if (m == 1)return 0; while (a > 1) {ll q = a / m; ll t = m; m = a % m, a = t; t = y; y = x - q * y; x = t;} if (x < 0)x += m0; return x;}
using namespace __gnu_pbds;
typedef tree<ll, null_type, less< ll>, rb_tree_tag, tree_order_statistics_node_update>ordered_set;
void functiontosolve()
{
    ll n;
    cin >> n;
    ll a[n];
    forr(i, 0, n) cin >> a[i];
    ll dp[n];
    dp[0] = 0;
    dp[1] = abs(a[1] - a[0]);
    forr(i, 2, n) {
        dp[i] = min(dp[i - 1] + abs(a[i - 1] - a[i]), dp[i - 2] + abs(a[i - 2] - a[i]));
    }
    cout << dp[n - 1] << "\n";
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    int test;
    test  = 1;
    forr(i, 1, test + 1) {
        functiontosolve();
    }
    return 0;
}


#include <stdio.h>
#int <math.h>
int H[10010];
int N;
int min(int a,int b){
  if(a>b){
    return b;
  }
  else{
    return a;
  }
}
int solve(int curr,int next){
  int cost = 0;
  curr--;
  next--;
  if(next==N){
    return 10000000000;
  }
  else{
    if(solve(curr,curr+1)<=solve(curr,curr+2)){
      cost = abs(H[curr] - H[curr+1]);
      }
      else{
        cost = abs(H[curr] - H[curr+2]);
      }
  }
  return cost;
}

int main(void){

  scanf("%d" , &N);
  int i = 0;
  for(i=0;i<N;i++){
    scanf("%d", &H[i]);
  }
  solve(1);

  return 0;
}


#include <stdio.h>
#define MIN(x, y) ((x) > (y) ? (y) : (x))
#define ABS(x) ((x) < 0 ? (-1*(x)) : (x))
int main()
{
  int n;
  scanf("%d",&n);
  int h[n];
  int i = 0;
  while (i < n)
  {
    scanf("%d",&h[i]);
    i++;
  }
  //一つ手前の足場までの最小値を記録し、それを利用して計算量を減らす
  i = 0;
  int dp[n];
  while (i < n)
  {
    dp[i] = 0;
    i++;
  }
  i = 0;
  dp[0] = 0;
  dp[1] = ABS(h[0] - h[1]);
  //printf("dp[1]:%d\n",dp[1]);
  if (n == 2)
  {
    printf("%d",dp[1]);
    return (0);
  }
  //i-1とi-2、足場iからコストの小さい方を選び、選んだ足場までのコストをそれに足す。
  if (ABS(h[2]-h[1]) < ABS(h[2]-h[0]))
    dp[2] = dp[1] + ABS(h[2]-h[1]);
  else
    dp[2] = dp[0] + ABS(h[2]-h[0]);
  if (n == 3)
  {
    printf("%d",dp[2]);
    return (0);
  }

  i = 3;
  int tmp;
  while (i < n)
  {
    //printf("i-1:%d\n",dp[i-1]);
    if (ABS(h[i]-h[i-1]) < ABS(h[i]-h[i-2]))
        dp[i] = dp[i-1] + ABS(h[i]-h[i-1]);
    else
        dp[i] = dp[i-2] + ABS(h[i]-h[i-2]);
    //printf("%d\n",tmp);
    //printf("h[i]-h[i-1]:%d h[i]-h[i-2]:%d\n",abs(h[i]-h[i-1]),abs(h[i]-h[i-2]));
    //printf("min:%d\n",min(abs(h[i]-h[i-1]),abs(h[i]-h[i-2])));
    //printf("i  :%d\n",dp[i]);
    i++;
  }
  printf("%d",dp[i-1]);
}


function Main(input) {
	input = input.split("\n");
	var n = parseInt(input[0], 10);
  	l2=input[1].split(" ");
  	var h=new Array(n);
  	var cost=new Array(n);
  	for (var i=0; i<n; i++){
     h[i]= parseInt(l2[i], 10);
    }
  	cost[0]=0;
  	cost[1]=Math.abs(h[1]-h[0]);

  	for (var i=2; i<n; i++){
     cost[i]=Math.min(cost[i-1]+Math.abs(h[i]-h[i-1]),cost[i-2]+Math.abs(h[i]-h[i-2]));
    }

  	console.log('%d',cost[n-1]);
  }
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  input = input.split("\n");
  var N = parseInt(input[0]);
  tmp = input[1].split(" ");
  h = new Array(N);
  for(var i=0;i<N;i++){
    h[i]=parseInt(tmp[i]);
  }
  var mins=new Array(N).fill(Math.pow(10,9)+1);
  mins[0]=0;
  mins[1]=Math.abs(h[1]-h[0]);
  for(var i=2;i<N;i++){
    mins[i]=Math.min(mins[i-1]+Math.abs(h[i]-h[i-1]),mins[i-2]+Math.abs(h[i]-h[i-2]));
  }
  var ans = mins[N-1];
  console.log('%s', ans);
  return ans;
}
// "実行する"ボタンを押した時に実行される関数 (デバッグ用)
function debug(n){
  var input = document.getElementById("input"+n).value;
  var ans=Main(input);
  var result="WA";
  if(ans==document.getElementById("output"+n).value.split("\n")[0]){
    result="AC";
  }
  document.getElementById("result"+n).innerHTML=result;
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  input = input.split("\n");
  const N = parseInt(input[0],10);
  const hn = input[1].split(' ').map((n) => {
    return parseInt(n, 10);
  });
  const h_max = Math.pow(10,9);
  console.log(dp(N,hn,h_max));
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));

function dp(N,hn,h_max) {
  const dp = [];
  dp[0] = 0;
  for (var i = 1; i < N; i++) {
    dp.push(h_max);
    if (i === 1) {
      dp[i] = Math.min(dp[i],dp[i-1] + Math.abs(hn[i-1] - hn[i]))
    } else {
      dp[i] = Math.min(dp[i],dp[i-1] + Math.abs(hn[i-1] - hn[i]),dp[i-2] + Math.abs(hn[i-2] - hn[i]))
    }
  }
  return dp[N-1];
}


process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

function ti(a){
    for(let i = 0; i < a.length; i++)
        a[i] = parseInt(a[i]);

    return a;
}

function main(){
    let [n,k] = ti(readline().split(' '));
    let h = ti(readline().split(' '));

    let dp = new Array(n);
    dp.fill(999999999999999);
    dp[0] = 0;
    for(let i = 0; i < n; i++){
        for(let j = 1; j < k+1; j++){
            if(i-j >= 0)
                dp[i] = Math.min(dp[i], Math.abs(h[i]-h[i-j]) + dp[i-j]);
            else
                break;
        }
    }

    console.log(dp[n-1]);
}


'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

function getArray(str) {
    return str.split(' ').map(x => Number(x));
}

function getInt(str) {
    return Number(str);
}

function getStrArray(str) {
    return str.split(' ').map(x => x);
}
// ---------------------------------------

function main() {
    const len = getInt(readline());
    const a = getArray(readline());
    const dp = new Array(len);
    dp.fill(-1);
    dp[0] = 0;
    dp[1] = Math.abs(a[1] - a[0]);
    const x = getCost(len-1, a);
    console.log(dp[len-1]);

    function getCost(i) {
        if(a < 0) {
            return 0;
        }
        if (dp[i] !== -1) {
            return dp[i];
        }

        dp[i] = Math.min(
            getCost(i-1) + Math.abs(a[i] - a[i - 1]),
            getCost(i-2) + Math.abs(a[i] - a[i - 2]),
        );

        return dp[i];
    }
}


'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

function getArray(str) {
    return str.split(' ').map(x => Number(x));
}

function getInt(str) {
    return Number(str);
}

function getStrArray(str) {
    return str.split(' ').map(x => x);
}
// ---------------------------------------

function main() {
    const len = getInt(readline());
    const a = getArray(readline());
    const dp = new Array(len);
    dp.fill(-1);
    dp[0] = 0;
    dp[1] = Math.abs(a[1] - a[0]);
    const x = getCost(len-1, a);
    console.log(dp[len-1]);

    function getCost(i, a) {
        if(a < 0) {
            return 0;
        }
        if (dp[i] !== -1) {
            return dp[i];
        }

        dp[i] = Math.min(
            dp[i - 1] + Math.abs(a[i] - a[i - 1]),
            dp[i - 2] + Math.abs(a[i] - a[i - 2]),
        );

        return dp[i];
    }
}


package main

import (
	"bufio"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

func chmin(a *int, b int) bool {
	if *a > b {
		*a = b
		return true
	}
	return false
}
func abs(a int) int {
	if a >= 0 {
		return a
	}
	return -a
}

var rdr = bufio.NewReaderSize(os.Stdin, 1000000)

func newLine() string {
	buf := make([]byte, 0, 1000000)
	for {
		l, p, e := rdr.ReadLine()
		if e != nil {
			panic(e)
		}
		buf = append(buf, l...)
		if !p {
			break
		}
	}
	return string(buf)
}

func main() {
	var n int
	n, _ = strconv.Atoi(newLine())
	h := make([]int, n+20)
	inputLine := strings.Split(newLine(), " ")
	for i, v := range inputLine {
		h[i], _ = strconv.Atoi(v)
	}
	dp := make([]int, n+20)
	for i := 0; i < n+20; i++ {
		dp[i] = math.MaxInt64
	}
	dp[0] = 0
	chmin(&dp[1], dp[0]+abs(h[1]-h[0]))
	for i := 2; i < n; i++ {
		chmin(&dp[i], dp[i-1]+abs(h[i]-h[i-1]))
		chmin(&dp[i], dp[i-2]+abs(h[i]-h[i-2]))
	}
	fmt.Println(dp[n-1])
}


package main

import (
	"bufio"
	"fmt"
	"os"
)

var sc = bufio.NewScanner(os.Stdin)

const inf = 1 << 60

func ri() (n int) {
	sc.Scan()
	for _, v := range sc.Bytes() {
		n = n*10 + int(v-48)
	}
	return
}

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func smaller(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func main() {
	sc.Split(bufio.ScanWords)
	n := ri()
	h := make([]int, n)
	for i := 0; i < n; i++ {
		h[i] = ri()
	}
	dp := make([]int, len(h))
	dp[0] = 0
	dp[1] = abs(h[1] - h[0])
	for i := 2; i < len(h); i++ {
		dp[i] = smaller(abs(h[i]-h[i-1])+dp[i-1], abs(h[i]-h[i-2])+dp[i-2])
	}
	fmt.Println(dp[len(dp)-1])
}


package main

import (
  "bufio"
  "fmt"
  "os"
  "strconv"
  "strings"
)

const size = 1000000
var reader = bufio.NewReaderSize(os.Stdin,size)
func NextLine() string {
  var line,buffer []byte
  var isPrefix bool = true
  var err error
  for ;isPrefix; {
    line,isPrefix,err = reader.ReadLine()
    if err != nil { panic(err) }
    buffer = append(buffer,line...)
  }
  return string(buffer)
}
func NextInt() int {
  var n int
  n,_ = strconv.Atoi(NextLine())
  return n
}
func NextIntArray() []int {
  var s []string = strings.Split(NextLine()," ")
  var n int = len(s)
  var a []int = make([]int,n)
  for i:=0;i<n;i++ {
    a[i],_ = strconv.Atoi(s[i])
  }
  return a
}

func main() {
  var n int = NextInt()
  var h []int = NextIntArray()
  var c []int = make([]int,n)
  c[0] = 0
  c[1] = abs(h[1]-h[0])
  for i:=2;i<n;i++ {
    c[i] = min(c[i-1]+abs(h[i]-h[i-1]),c[i-2]+abs(h[i]-h[i-2]))
  }
  fmt.Println(c[n-1])
}
func abs(n int) int {
  if n < 0 { return -n }
  return n
}
func min(n int,m int) int {
  if n < m { return n }
  return m
}


package main

import (
	"math"
)

func minPossibleTotalCost(n int, height []int) int {
	dp := make([]int, n)
	dp[0] = 0
	for i := 1; i < n; i++ {
		dp[i] = 1 << 32
	}
	for i := 0; i < n; i++ {
		for _, j := range []int{i + 1, i + 2} {
			if j < n {
				cost := int(math.Abs(float64(height[i] - height[j])))
				dp[j] = min(dp[j], cost+dp[i])
			}
		}
	}
	return dp[n-1]
}

func min(a int, b int) int {
	if a < b {
		return a
	}
	return b
}


import (
	"math"
)

func solution(n int, height []int) int {
	dp := make([]int, n)
	dp[0] = 0
	for i := 1; i < n; i++ {
		dp[i] = 1 << 32
	}
	for i := 0; i < n; i++ {
		for _, j := range []int{i + 1, i + 2} {
			if j < n {
				cost := int(math.Abs(float64(height[i] - height[j])))
				dp[j] = min(dp[j], cost+dp[i])
			}
		}
	}
	return dp[n-1]
}

func min(a int, b int) int {
	if a < b {
		return a
	}
	return b
}


import (
	"math"
)

func minPossibleTotalCost(n int, height []int) int {
	dp := make([]int, n)
	dp[0] = 0
	for i := 1; i < n; i++ {
		dp[i] = 1 << 32
	}
	for i := 0; i < n; i++ {
		for _, j := range []int{i + 1, i + 2} {
			if j < n {
				cost := int(math.Abs(float64(height[i] - height[j])))
				dp[j] = min(dp[j], cost+dp[i])
			}
		}
	}
	return dp[n-1]
}

func min(a int, b int) int {
	if a < b {
		return a
	}
	return b
}


ashiba_num = gets.to_i
ashiba_cost = gets.split(' ').map(&:to_i)

dP = []
dP[0] = 0
dP[1] = (ashiba_cost[1] - ashiba_cost[0]).abs

range = 2..ashiba_num - 1
range.each do |move|
    comp1 = dP[move - 1] + (ashiba_cost[move] - ashiba_cost[move - 1]).abs
    comp2 = dP[move - 2] + (ashiba_cost[move] - ashiba_cost[move - 2]).abs

    comp1 >= comp2 ? dP[move] = comp2 : dP[move] = comp1

end

p dP.last


N=gets.to_i
a=gets.split.map(&:to_i)
dp=[]
dp[0]=0
dp[1]=(a[0]-a[1]).abs
for i in 2..N-1
    b=dp[i-2]+(a[i-2]-a[i]).abs
    c=dp[i-1]+(a[i-1]-a[i]).abs
    dp[i]=b > c ? c : b
end
puts dp[N-1]


n = gets.to_i
h = gets.chomp.split(" ").map(&:to_i)

dp = Array.new(n, Float::INFINITY)
dp[0] = 0
dp[1] = (h[1] - h[0]).abs

for i in 2.. n - 1
    step1 = dp[i - 1] + (h[i] - h[i - 1]).abs
    step2 = dp[i - 2] + (h[i] - h[i - 2]).abs

    if step1 < step2
        dp[i] = step1
    else
        dp[i] = step2
    end
end

puts dp[n - 1]


N = gets.chomp.to_i
H = gets.chomp.split.map(&:to_i)

@dp = Array.new(N) { 0 }
(0...N).each do |i|
  if i == 0
   @dp[i] = 0
  puts [i, @dp[i]]
   next
  elsif i == 1
   @dp[i] = @dp[i-1] + (H[i-1] - H[i]).abs
  puts [i, @dp[i]]
   next
  else
    @dp[i] = [@dp[i-1] + (H[i-1] - H[i]).abs,
              @dp[i-2] + (H[i-2] - H[i]).abs].min
  puts [i, @dp[i]]
  end

end


	# A - Frog 1
# https://atcoder.jp/contests/dp/tasks/dp_a

N = gets.chomp.to_i
H = gets.chomp.split.map(&:to_i)

@memo = Array.new(N) {Array.new(H.reduce(:+)) { nil }}

# c そこまでのコスト
def solve(i, c)
  #p [i, c,  @memo[i][c] ]
  return @memo[i][c] unless @memo[i][c].nil?

  if i >= N-1
    @memo[i][c] = c
    return @memo[i][c]
  end

  if i >= N-2
    @memo[i][c] = solve(i+1, c + (H[i+1] - H[i]).abs)
    return @memo[i][c]
  end

  # when jump to i+1
  c1 = solve(i+1, c + (H[i+1] - H[i]).abs)
  # when jump to i+2
  c2 = solve(i+2, c + (H[i+2] - H[i]).abs)

  @memo[i][c] = [c1,c2].min
  return @memo[i][c]
end

puts solve(0, 0)


require 'pp'

# Nと空白区切の入力値を数値の配列で返却する
def gets_n_and_i_list()
  return gets.chomp.to_i, gets.chomp.split(" ").map(&:to_i)
end

def min(a, b)
  return a < b ? a : b
end

n, hlist = gets_n_and_i_list
INF = 100000 #Float::INFINITY

dp = Array.new(n, INF)
dp[0] = 0

0.upto(n-1) do |i|
  if i + 1 < n
    diff1 = (hlist[i + 1] - hlist[i]).abs + dp[i]
    dp[i + 1] = min(diff1, dp[i+1])
  end

  if i + 2 < n
    diff2 = (hlist[i + 2] - hlist[i]).abs + dp[i]
    dp[i + 2] = min(diff2, dp[i+2])
  end

end

puts dp.last


use std::cmp::*;
use std::io::*;
use std::str::FromStr;
use utils::*;

pub fn main() {
    let i = stdin();
    let mut o = Vec::new();
    run(i.lock(), &mut o);
    stdout().write_all(&o).unwrap();
}

fn run<R: BufRead, W: Write>(i: R, o: &mut W) {
    let mut i = CpReader::new(i);
    let n = i.read::<usize>();
    let h = i.read_vec::<isize>(n);

    writeln!(o, "{}", solve(&h)).unwrap();
}
fn solve(h: &[isize]) -> isize {
    let mut c: [isize; 2] = [0, (h[0] - h[1]).abs()];

    for i in 2..h.len() {
        c = [
            c[1],
            min(
                c[0] + (h[i] - h[i - 2]).abs(),
                c[1] + (h[i] - h[i - 1]).abs(),
            ),
        ];
    }
    c[1]
}

mod utils {
    use super::*;

    pub struct CpReader<R: BufRead> {
        r: R,
        s: String,
    }

    macro_rules! fn_read {
        { $f:ident($($t:ident),*) } => {
            #[allow(dead_code)]
            pub fn $f<$($t: FromStr),*>(&mut self) -> ($($t),*) {
                let i = &mut self.read_line().split(' ');
                ($(read_next::<$t,_>(i)),*)
            }
        };
    }

    impl<R: BufRead> CpReader<R> {
        pub fn new(r: R) -> Self {
            CpReader {
                r: r,
                s: String::new(),
            }
        }
        pub fn read_line(&mut self) -> &str {
            self.s.clear();
            self.r.read_line(&mut self.s).unwrap();
            self.s.trim()
        }

        pub fn read<T: FromStr>(&mut self) -> T {
            self.read_line().parse().ok().unwrap()
        }
        fn_read! { read2(T1, T2) }
        fn_read! { read3(T1, T2, T3) }
        fn_read! { read4(T1, T2, T3, T4) }
        fn_read! { read5(T1, T2, T3, T4, T5) }

        pub fn read_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            self.read_line()
                .split(' ')
                .take(n)
                .map(|x| x.parse().ok().unwrap())
                .collect()
        }
    }
    fn read_next<'a, T: FromStr, I: Iterator<Item = &'a str>>(i: &mut I) -> T {
        i.next().unwrap().parse().ok().unwrap()
    }

}


#![allow(unused_imports)]

#[macro_use]
mod _input {
    use std::fmt;
    use std::io::{self, Read};
    use std::str::{self, FromStr};

    macro_rules! input {
        ($($name:ident : $t:tt),*,) => {
            input!($($name: $t),*)
        };
        ($($name:ident : $t:tt),*) => {
            let mut _scanned = ::_input::Scanned::new(::std::io::stdin(), 1024);
            $(
                let $name = _read_value!(_scanned, $t);
            )*
        };
    }

    macro_rules! _read_value {
        ($scanned:expr, ($($t:tt),*)) => {
            ($(_read_value!($scanned, $t)),*)
        };
        ($scanned:expr, [$t:tt; $n:expr]) => {
            (0..$n).map(|_| _read_value!($scanned, $t)).collect::<Vec<_>>()
        };
        ($scanned:expr, _bytes) => {
            _read_value!($scanned, String).into_bytes()
        };
        ($scanned:expr, _index) => {
            _read_value!($scanned, usize) - 1
        };
        ($scanned:expr, $t:ty) => {
            $scanned.next::<$t>()
        };
    }

    #[derive(Default)]
    pub struct Scanned {
        buf: Vec<u8>,
        pos: usize,
    }

    impl Scanned {
        pub fn new<R: Read>(mut input: R, estimated: usize) -> Self {
            let mut buf_ = Vec::with_capacity(estimated);
            let _ = io::copy(&mut input, &mut buf_).unwrap();
            if buf_.last() != Some(&b'\n') {
                buf_.push(b'\n'); // input may not end with '\n'
            }
            debug_assert!(str::from_utf8(&buf_).is_ok());
            debug_assert!(buf_.iter().all(|&c| u32::from(c) <= 0x7F));
            Scanned { buf: buf_, pos: 0 }
        }

        #[inline]
        pub fn next<T: FromStr>(&mut self) -> T
        where
            T::Err: fmt::Debug,
        {
            let mut start = None;
            loop {
                match (self.buf[self.pos], start.is_some()) {
                    (b' ', true) | (b'\n', true) => break,
                    (_, true) | (b' ', false) | (b'\n', false) => self.pos += 1,
                    (_, false) => start = Some(self.pos),
                }
            }
            let target = &self.buf[start.unwrap()..self.pos];
            unsafe { str::from_utf8_unchecked(target) }.parse().unwrap()
        }
    }
}

#[allow(dead_code)]
mod output {
    use std::io::{self, BufWriter, StdoutLock, Write as _Write};

    pub fn with_stdout<F: FnMut(&mut BufWriter<StdoutLock>)>(mut f: F) {
        let stdout = io::stdout();
        let mut stdout = BufWriter::new(stdout.lock());
        f(&mut stdout);
        stdout.flush().unwrap();
    }
}

use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::io::Write;
use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Mul, MulAssign, Neg, Not, Rem, RemAssign, Sub, SubAssign,
};
use std::str::{self, FromStr};
use std::{char, cmp, f32, f64, fmt, i16, i32, i64, i8, thread, u16, u32, u64, u8};

fn main() {
    input! {
        n: usize,
        hs: [i64; n],
    }
    let mut dp = vec![0; n];
    dp[1] = (hs[0] - hs[1]).abs();
    for i in 2..n {
        dp[i] = cmp::min(
            dp[i - 2] + (hs[i] - hs[i - 2]).abs(),
            dp[i - 1] + (hs[i] - hs[i - 1]).abs(),
        );
    }
    println!("{}", dp[n - 1]);
}


use std::collections::*;
use std::io;
use std::cmp::*;

fn main(){
    let t_cases = 1;
    for _ in 0..t_cases{
        solve();
    }
}

fn solve(){
    let mut buf = String::new();
    io::stdin().read_line(&mut buf).unwrap();
    buf.clear();
    io::stdin().read_line(&mut buf).unwrap();
    let a = buf
                .trim()
                .split_whitespace()
                .map(|x| x.parse::<i32>().unwrap())
                .collect::<Vec<i32>>();
    let n = a.len();
    let mut dp = vec![10i32.pow(9)+7;n];
    dp[0] = 0;
    for i in 0..n{
        if i >= 1{
            dp[i] = min(dp[i],dp[i-1]+(a[i]-a[i-1]).abs());
        }
        if i >=2{
            dp[i] = min(dp[i],dp[i-2]+(a[i]-a[i-2]).abs());
        }
    }
    println!("{}",dp[n-1]);
}


#![allow(unused_imports)]

use text_io::*;
use proconio::*;
use std::collections::*;
use std::process::exit;
use std::cmp::*;
use itertools::Itertools;

fn main() {
    proconio::input! {
        n: usize,
        mut p: [isize;n],
        }
    let mut q= vec![0;1000000000000];
    q[1]=(p[1]-p[0]).abs();
    for i in 0..n-2 {
        q[i+1]=min((p[i+1]-p[i]).abs()+q[i],q[i+1]);
        q[i+2]=(p[i+2]-p[i]).abs()+q[i];
    }
    q[n-1]=min((p[n-2]-p[n-1]).abs()+q[n-2],q[n-1]);
    println!("{}",q[n-1]);

    // g[i] = min( g[i-1] + f[i-1], g[i-2] + f[i-2])
    //
    // g[i+1] = min( g[i+1], g[i] + f[i+1],)
    //
}


#![allow(dead_code, unused_imports, deprecated)]
use std::cmp::{max, min, Reverse};
use std::collections::*;
use maplit::*;
use num::Integer;
use proconio::input;
use proconio::marker::*;
use proconio::fastout;

const INF : i64 = 1000000007;

#[fastout]
fn main() {
  input! {
    n : usize,
  };

  let mut dp = vec![vec![0usize; 3]; n];

  for i in 0..n {
    input! {
      a : usize, b : usize, c : usize,
    };

    if i == 0 {
      dp[0][0] = a;
      dp[0][1] = b;
      dp[0][2] = c;
    } else {
      dp[i][0] = a + max(dp[i - 1][1], dp[i - 1][2]);
      dp[i][1] = b + max(dp[i - 1][2], dp[i - 1][0]);
      dp[i][2] = c + max(dp[i - 1][0], dp[i - 1][1]);
    }
  }

  println!("{}", dp[n - 1].iter().max().unwrap());
}


//use proconio::{input, fastout};
use proconio::input;
use std::cmp::min;

//#[fastout]
fn main() {
    input! {
        n: usize,
        h: [i32; n],
    }
    let mut dp = vec![0; n];
    let m = 2;
    dp[1] = (h[1] - h[0]).abs();
    for i in m..n {
        let mut dpi = dp[i - 1] + (h[i] - h[i - 1]).abs();
        for j in 1..(m + 1) {
            dpi = min(dpi, dp[i - j] + (h[i] - h[i - j]).abs());
        }
        dp[i] = dpi;
    }

    println!("{}", dp[n - 1]);
}


let n = Int(readLine()!)
let arr = readLine()!.split(separator: " ").map({Int($0)!})

var costArr = [Int](repeating: 0, count: arr.count)
costArr[1] = abs(arr[0] - arr[1])

for i in 2 ..< arr.count {
    costArr[i] = min(costArr[i-1] + abs(arr[i] - arr[i-1]), costArr[i-2] + abs(arr[i] - arr[i-2]))
}
print(costArr.last!)


import Foundation
//漸化式
//var fib = [Int](repeating: 0, count: 100)
//fib[0] = 1
//fib[1] = 1
//for i in 2 ..< 50 {
//    fib[i] = fib[i-1] + fib[i-2]
//    print(fib[i])
//}

let N = Int(readLine()!)!
let h_line = readLine()!.split(separator: " ").map({Int($0)!})

var dp = [Int](repeatElement(0, count: N))
var cost = 0
dp[0] = 0
dp[1] = abs(h_line[1] - h_line[0])
for i in 2 ..< h_line.count {
    dp[i] = min(abs(h_line[i] - h_line[i-1]) + dp[i-1], abs(h_line[i-2] - h_line[i]) + dp[i-2])
}
print(dp.last!)


let N = Int(readLine()!)!
let h = readLine()!.split(separator: " ").map { Int($0)! }
var dp: [Int] = .init(repeating: Int.max, count: N)
dp[0] = 0
for i in 0..<N-1 {
  dp[i + 1] = min(dp[i + 1], dp[i] + abs(h[i+1] - h[i]))
  if i + 2 < N {
  	dp[i + 2] = min(dp[i + 2], dp[i] + abs(h[i+2] - h[i]))
  }
}
print(dp[N-1])


import Foundation
//漸化式
//var fib = [Int](repeating: 0, count: 100)
//fib[0] = 1
//fib[1] = 1
//for i in 2 ..< 50 {
//    fib[i] = fib[i-1] + fib[i-2]
//    print(fib[i])
//}

let N = Int(readLine()!)!
let h_line = readLine()!.split(separator: " ").map({Int($0)!})

var dp = [Int](repeatElement(0, count: N))
var cost = 0
dp[0] = 0
dp[1] = abs(h_line[1] - h_line[0])
for i in 2 ..< h_line.count {
    dp[i] = min(abs(h_line[2] - h_line[1]) + dp[i-1], abs(h_line[2] - h_line[0]) + dp[i-2])
}
print(dp)
print(dp.last!)


import Foundation
//漸化式
//var fib = [Int](repeating: 0, count: 100)
//fib[0] = 1
//fib[1] = 1
//for i in 2 ..< 50 {
//    fib[i] = fib[i-1] + fib[i-2]
//    print(fib[i])
//}

let N = Int(readLine()!)!
let h_line = readLine()!.split(separator: " ").map({Int($0)!})

var dp = [Int](repeatElement(0, count: 100))
var cost = 0
dp[0] = 0
dp[1] = h_line[1] - h_line[0]
for i in 2 ..< h_line.count {
    dp[i] = min(abs(h_line[2] - h_line[1]) + dp[i-1], abs(h_line[2] - h_line[0]) + dp[i-2])
}
print(dp.reduce(0, +))


let n = Int(readLine()!)!
let h = readLine()!.split{$0 == " "}.map{Int($0)!}
var d = [Int](repeating: 0, count: n), c = d

func f(_ x: Int)->Int {
    if x <= 1 {
        return abs(h[x] - h[0])
    }
    if c[x] == 1 {
        return d[x]
    }
    c[x] = 1

    d[x] = min(f(x - 1) + abs(h[x] - h[x-1]), f(x - 2) + abs(h[x] - h[x-2]))
    return d[x]
}

print(f(n-1))


import * as fs from "fs";

// inputで受け取り配列化する
const input = fs.readFileSync("/dev/stdin", "utf8").split("\n");
const N = Number(input[0]);
const h = input[1].split(" ").map(Number);

const dp = Array(N).fill(Infinity);

dp[0] = 0;
dp[1] = Math.abs(h[1] - h[0]);

for (let index = 2; index < N; index++) {
  const oneJump = Math.abs(h[index] - h[index - 1]) + dp[index - 1];
  const twoJump = Math.abs(h[index] - h[index - 2]) + dp[index - 2];
  dp[index] = Math.min(oneJump, twoJump);
}

console.log(dp[dp.length - 1]);


// https://atcoder.jp/contests/dp/tasks/dp_a

import * as fs from "fs";

const split_number = (str: string): number[] => {
  return str.split(" ").map((v: string) => +v);
};

function main(input: string) {
  const lines = input.split("\n");
  const [n] = split_number(lines[0]);

  const h: number[] = split_number(lines[1]);
  let dp: number[] = new Array(n).fill(Infinity);
  dp[0] = 0;

  let result: number = 0;

  for (let i = 0; i < n; i++) {
    if (i >= 2) {
      dp[i] = Math.min(dp[i], dp[i - 2] + Math.abs(h[i] - h[i - 2]));
    }
    if (i >= 1) {
      dp[i] = Math.min(dp[i], dp[i - 1] + Math.abs(h[i] - h[i - 1]));
    }
  }

  console.log(dp[n - 1]);
}

main(fs.readFileSync("/dev/stdin", "utf8"));


function main(input: string) {
  const [N, hs] = input.split("\n").map((v,i) => i % 2 === 0 ? parseInt(v) : v.split(" ").map(vv=>parseInt(vv)));
  const arr = new Array(N);
  arr.fill(Infinity);
  arr[0] = 0 // 初期値
  for (let i = 1; i < N; i++) {
    // 2個前から
    if (i - 2 >= 0) {
      arr[i] = Math.min(arr[i], arr[i-2] + Math.abs(hs[i] - hs[i-2]));
    }
    // 1個前から
    if (i - 1 >= 0) {
      arr[i] = Math.min(arr[i], arr[i-1] + Math.abs(hs[i] - hs[i-1]));
    }
  }
  console.log(arr[N-1]);
}

main(
  require("fs")
    .readFileSync("/dev/stdin", "utf8")
    .trim()
);


const lines: string[] = [];
const reader = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});
reader.on("line", function (line: string) {
  lines.push(line);
});

let dp: any;
let inputSize;

//数字の配列
let input: any;

reader.on("close", function () {
  inputSize = Number(lines[0]);

  //数字の配列
  input = lines[1].split(" ").map(Number);
  dp = [inputSize];
  for (let i = 0; i < inputSize; i++)
    dp[i] = {
      value: Infinity,
    };

  dp[0] = { value: 0 };

  // for (let i = 1; i < dp.length; i++) {
  //   chmin(dp[i], { value: dp[i - 1].value + abs(input[i] - input[i - 1]) });
  //   if (i > 1)
  //     chmin(dp[i], { value: dp[i - 2].value + abs(input[i] - input[i - 2]) });
  // }

  console.log(rec(Number(inputSize) - 1).value);
  // console.log(dp);
});

function rec(i: number): any {
  if (dp[i] < Infinity) return dp[i];

  if (i === 0) return { value: 0 };

  let res = { value: Infinity };

  if (i > 0)
    chmin(res, { value: rec(i - 1).value + abs(input[i] - input[i - 1]) });
  if (i > 1)
    chmin(res, { value: rec(i - 2).value + abs(input[i] - input[i - 2]) });

  dp[i] = res;
  return dp[i];
}

function chmin(a: any, b: any): boolean {
  if (a.value > b.value) {
    a.value = b.value;
    return true;
  }
  return false;
}

function chmax(a: any, b: any): boolean {
  if (a.value < b.value) {
    a = b;
    return true;
  }
  return false;
}

function abs(val: number) {
  return val < 0 ? -val : val;
}


const lines: string[] = [];
const reader = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});
reader.on("line", function (line: string) {
  lines.push(line);
});

let dp: any;
let inputSize;

//数字の配列
let input: any;

reader.on("close", function () {
  inputSize = Number(lines[0]);

  //数字の配列
  input = lines[1].split(" ").map(Number);
  dp = [inputSize];
  for (let i = 0; i < inputSize; i++)
    dp[i] = {
      value: Infinity,
    };

  dp[0] = { value: 0 };

  // for (let i = 1; i < dp.length; i++) {
  //   chmin(dp[i], { value: dp[i - 1].value + abs(input[i] - input[i - 1]) });
  //   if (i > 1)
  //     chmin(dp[i], { value: dp[i - 2].value + abs(input[i] - input[i - 2]) });
  // }

  console.log(rec(Number(inputSize) - 1).value);
  console.log(dp);
});

function rec(i: number): any {
  if (dp[i] < Infinity) return dp[i];

  if (i === 0) return { value: 0 };

  let res = { value: Infinity };

  if (i > 0)
    chmin(res, { value: rec(i - 1).value + abs(input[i] - input[i - 1]) });
  if (i > 1)
    chmin(res, { value: rec(i - 2).value + abs(input[i] - input[i - 2]) });

  dp[i] = res;
  return dp[i];
}

function chmin(a: any, b: any): void {
  if (a.value > b.value) {
    a.value = b.value;
    // return true;
  }
  // return false;
}

function chmax(a: any, b: any): boolean {
  if (a.value < b.value) {
    a = b;
    return true;
  }
  return false;
}

function abs(value: number) {
  return Math.abs(value);
}


const lines: string[] = [];
const reader = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
});
reader.on("line", function (line: string) {
  lines.push(line);
});

let dp: any;
let inputSize;

//数字の配列
let input: any;

reader.on("close", function () {
  inputSize = Number(lines[0]);

  //数字の配列
  input = lines[1].split(" ").map(Number);
  dp = [inputSize];
  for (let i = 0; i < inputSize; i++)
    dp[i] = {
      value: Infinity,
    };

  dp[0] = { value: 0 };

  // for (let i = 1; i < dp.length; i++) {
  //   chmin(dp[i], { value: dp[i - 1].value + abs(input[i] - input[i - 1]) });
  //   if (i > 1)
  //     chmin(dp[i], { value: dp[i - 2].value + abs(input[i] - input[i - 2]) });
  // }

  console.log(rec(Number(inputSize) - 1).value);
  // console.log(dp);
});

function rec(i: number): any {
  if (dp[i] < Infinity) return dp[i];

  if (i === 0) return { value: 0 };

  let res = { value: Infinity };

  if (i > 0)
    chmin(res, { value: rec(i - 1).value + abs(input[i] - input[i - 1]) });
  if (i > 1)
    chmin(res, { value: rec(i - 2).value + abs(input[i] - input[i - 2]) });

  dp[i] = res;
  return dp[i];
}

function chmin(a: any, b: any): boolean {
  if (a.value > b.value) {
    a.value = b.value;
    return true;
  }
  return false;
}

function chmax(a: any, b: any): boolean {
  if (a.value < b.value) {
    a = b;
    return true;
  }
  return false;
}

function abs(value: number) {
  return Math.abs(value);
}


import sys
if sys.argv[-1] == 'ONLINE_JUDGE':
    import os, zlib, base64
    open('solve.pyx', 'wb').write(zlib.decompress(base64.b85decode("c${TYO>cuR480@qAH2g<SksD5J4|Tok8~W85Fi=^lxC{7Uq74hU0=X{&(AMTO53&2Xd%xxXSJz7>bCE!gI2XS<-(vOg8X%LXU;vhylGT3lX}ZdrAE@IQs{2RE9GR(EkmL<t_%ZNs1oq^`kGMW(1(Ga6!i>F7X}`H7r5y^)s+#F<9Kdtv{BTL6HF9?=_=i%VE`DDGzbO~GDv*+Uh77|Wh7Au1V>|0yp(l`$OpW=ry#82-wQ%&5*=L<I3nkS91mLMeyjnxoC_Mo3uVbQ@U1`8@2@<^5lK3Aat{slZ0e;f-VC71YKCFZGT@9(su?&&4({63n|X#@)0TYNZqu@}piynS!l;c`8{%8;w6tA`FP1qj<+5Xskk~=E1`badh}FFHdOq<Z@*POwP?JBF$%S|<lLNOc5Aw%s(BC5>_v-Un{8mi7T;8d_YO*KO;Xw>(82E=B9iEFXbHIzhll}vB`qr2")))
    os.system('cythonize -i -3 -b solve.pyx')
import solve


import sys
if sys.argv[-1] == 'ONLINE_JUDGE':
    import os, zlib, base64
    open('solve.pyx', 'wb').write(zlib.decompress(base64.b85decode("c${TY%Wi`(5WFMt58Fc(Xq*VD9x7D&BPj>l7_bTkIj*Ai>${5yulNExGoBr<UD>{aRttH)I;%|$Qg=gd9dxR@Di;P73FNP9dUGDQ<!!6lSu|K~YBh-_ms0mLUn?gYZW#)-aa9<|QdNMzm)C?=0Ye!0PSL>Nlrr!HyueleslJL(9LLK>v^G%;rmuCIg#qB2DZxNO4vB|vjcygBlZci;a!M4%3#=<-KH%*=17Q{aUKnzd7$r^Mh?)~>JZY8tu?FNSSF3obEX4)B&4>QOg%{W&$?iM3r$#)#@1-i<G$3Tv!!YO=a7HK93>>2bH|?5DKSQZ$O1|v2Wz}2I=r-M5)Wxd_@vZhgv>n8k$Q*}~?$i?{b`*|*!&44o)o(qXPyC2tN78cW$sb`#As%5$;I{B+f6Pb!JtGS5K99vu#l*|yora61crqIw#8`%bf6>w5x%@H*ya+t$KlVq{`2")))
    os.system('cythonize -i -3 -b solve.pyx')
import solve


n, m = map(int, input().split())
lis = []
ans = 0
for _ in range(m):
  a, b = map(int, input().split())
  if len(lis) > 0:
    c = 0
    for i in range(len(lis)):
      if a in lis[i] or b in lis[i]:
        lis[i].append(a)
        lis[i].append(b)
        c += 1
        break
    if c == 0:
      lis.append([a, b])
  else:
    lis.append([a, b])

for x in lis:
  ans = max(ans, len(set(x)))

print(ans)


from collections import Counter

n, m = map(int, input().split())
if m == 0:
  print("0")
else:
  ab = [map(int, input().split()) for _ in range(m)]
  a, b = [list(i) for i in zip(*ab)]

  a.extend(b)
  c = Counter(a)
  most = c.most_common(1)[0][0]

  temp = []
  for i in range(m):
    if a[i] == most or b[i] == most:
      if a[i] == b[i]:
        continue
      temp.append(a[i])
      temp.append(b[i])
  temp = list(set(temp))
  print(len(temp))


from collections import Counter

n, m = map(int, input().split())
ab = [map(int, input().split()) for _ in range(m)]
a, b = [list(i) for i in zip(*ab)]

a.extend(b)
c = Counter(a)
most = c.most_common(1)[0][0]

temp = []
for i in range(m):
  if a[i] == most or b[i] == most:
    if a[i] == b[i]:
      continue
    temp.append(a[i])
    temp.append(b[i])
temp = list(set(temp))
print(len(temp))