#include <stdio.h>

#include <stdlib.h>

#include <string.h>


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

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


int* arr;

int n, num;

int dy[101][51]; //배열 pos위치까지 블럭이 cnt개수일때 최대값 


void function(int pos, int sum, int starting, int min1, int max1, int cnt) {

int mi,ma;

if(cnt>num || pos==n) return; //블럭의 개수가 주어진 개수보다 크거나, 현재배열원소가 마지막을 벗어난 경우 리턴

if(!starting) { // 처음시작하거나 이전 pos에서 블럭을 끝냈기 때문에 블럭을 시작한 경우. 블럭이 1개이기때문에 여기서 끝낼순 없고 블럭을 이어나간다.

return function(pos+1, sum, 1, arr[pos], arr[pos], cnt+1);

}

else {//블럭이 이전 pos에 이어 지속되는 경우

mi = min(min1, arr[pos]); //지속되는 블럭중에서 최대최소값과 현재 위치원소를 비교하여 최대최소를 다시 구한다 

ma = max(max1, arr[pos]);

if(dy[pos][cnt] < sum + ma-mi) { //배열 pos위치까지 블럭개수가 cnt일때 이전에 체크했던 것보다 크다면 진행. 아니라면 최대가 아니기 때문에 무의미

dy[pos][cnt] = sum + ma-mi;  //블럭을 pos위치에서 끝맺음 맺고, pos위치에서 블럭의 개수가 cnt일때, 최대값으로 갱신

function(pos+1, sum + ma-mi, 0, 0, 0, cnt); //블럭을 다시 시작

}

function(pos+1, sum, 1, mi, ma, cnt); // pos위치에서 블럭을 끝내고 다시시작하는 경우와 이어나가는 경우가 존재하기 때문에, 다음원소도 이어나가도록 호출.

}

}


int main() {

int i;


scanf("%d", &n);

scanf("%d", &num);


arr = (int*)malloc(sizeof(int)*n);

for(i=0; i<n; i++)

scanf("%d",&arr[i]);

function(0, 0, 0, 0, 0, 0);

printf("%d\n", dy[n-1][num]);//배열원소 끝까지, 블럭개수가 문제에서 주어진 수만큼의 최대값.

return 0;

}