func CrusherImpl(task *tsp_types.TaskType) (bool, *tsp_types.TaskType, *tsp_types.TaskType) {
	success, additional_cost := calculate_plus_cost(*task.Matrix, task.Size)
	if success != true {
		return false, nil, nil
	}
	task.CurrCost += additional_cost
	heavier_zero := find_heavier_zero(*task.Matrix, task.Size)
	//prepare data for recursive call
	sub_dt := generate_sub_task_data(task.Matrix, task.RowMapping, task.ColMapping, task.Jumps, heavier_zero, task.Size)
	//call this function recursively
	task1 := tsp_types.TaskType{sub_dt.Matrix, sub_dt.RowMapping, sub_dt.ColMapping, sub_dt.Jumps, task.CurrCost, task.MinCost, task.Size - 1}
	(*task.Matrix)[heavier_zero.Row*task.Size+heavier_zero.Col] = tsp_types.POSITIVE_INF
	return true, &task1, task
}
func SolveImpl(task tsp_types.TaskType, gl_min_cost *tsp_types.GlobalCostType) (tsp_types.AnswerType, bool) {
	if gl_min_cost.Get() < task.MinCost {
		return tsp_types.ERROR_ANSWER, false
	}
	if (task.Size == 0) || (task.Size == 1) {
		return tsp_types.ERROR_ANSWER, true
	}
	success, additional_cost := calculate_plus_cost(*task.Matrix, task.Size)
	if !success {
		return tsp_types.ERROR_ANSWER, true
	}
	task.CurrCost += additional_cost
	heavier_zero := find_heavier_zero(*task.Matrix, task.Size)
	// if task.Size is 2 end recursion
	if task.Size == 2 {
		next_city := heavier_zero.Col
		previous_city := heavier_zero.Row
		if ((*task.Matrix)[(previous_city^1)*2+(next_city^1)] == 0) &&
			((*task.Matrix)[(previous_city^1)*2+next_city] == tsp_types.POSITIVE_INF) &&
			((*task.Matrix)[previous_city*2+(next_city^1)] == tsp_types.POSITIVE_INF) {
			jumps := make([]tsp_types.JumpType, 2)
			jumps[0] = tsp_types.JumpType{task.RowMapping[heavier_zero.Row], task.ColMapping[heavier_zero.Col]}
			jumps[1] = tsp_types.JumpType{task.RowMapping[heavier_zero.Row^1], task.ColMapping[heavier_zero.Col^1]}
			for j := range task.Jumps {
				jumps = append(jumps, task.Jumps[j])
			}
			return tsp_types.AnswerType{jumps, task.CurrCost}, true
		} else {
			return tsp_types.ERROR_ANSWER, true
		}
	}
	// prepare data for recursive call
	sub_dt := generate_sub_task_data(task.Matrix, task.RowMapping, task.ColMapping, task.Jumps, heavier_zero, task.Size)
	//call this function recursively
	answer, less_global := SolveImpl(tsp_types.TaskType{sub_dt.Matrix, sub_dt.RowMapping, sub_dt.ColMapping, sub_dt.Jumps, task.CurrCost, task.MinCost, task.Size - 1}, gl_min_cost)
	if !less_global {
		return tsp_types.ERROR_ANSWER, false
	}
	//print_answer(answer, "GOT ANSWER")
	final_path := []tsp_types.JumpType{}
	if answer.Cost < task.MinCost {
		final_path = answer.Jumps
		task.MinCost = answer.Cost
	}
	//right_path
	if (task.CurrCost + heavier_zero.Weight) < task.MinCost {
		//correct first one
		(*task.Matrix)[heavier_zero.Row*task.Size+heavier_zero.Col] = tsp_types.POSITIVE_INF
		answer, less_global = SolveImpl(task, gl_min_cost)
		if !less_global {
			return tsp_types.ERROR_ANSWER, false
		}
		if answer.Cost < task.MinCost {
			final_path = answer.Jumps
			task.MinCost = answer.Cost
		}
	}
	// return answer
	if task.MinCost < tsp_types.POSITIVE_INF {
		return tsp_types.AnswerType{final_path, task.MinCost}, true
	} else {
		return tsp_types.ERROR_ANSWER, true
	}
}