The concept of subtasks was first formally introduced in IOI 2010. The idea is basically to split a problem into two or more smaller problems with gradually increasing difficulty, and assign them different points.

For example:

- N = 1
- 1 ≤ K ≤ 100

- 1 ≤ N ≤ 100
- K = 1

- 1 ≤ N ≤ 100
- 1 ≤ K ≤ 100

In this type type of problem, you won’t be writing a `Constraints()` method. Instead, you will be writing `SubtaskX()` methods, where `X` is the subtask number.

Note

A subtask is basically just a set of constraints. It can be specified by the method `SubtaskX()`, where `X` is the subtask number. Inside the method, the constraint specifications are given, similar to what you usually do in the `Constraints()` method. Points for each subtask can be given using `Points()` method, that takes a floating-point number argument as the points.

Thus, the above example can be implemented as:

```void Subtask1() {
Points(20);

CONS(N == 1);
CONS(1 <= K && K <= 100);
}

Points(20);

CONS(1 <= N && N <= 100);
CONS(K == 1);
}

Points(60);

CONS(1 <= N && N <= 100);
CONS(1 <= K && K <= 100);
}
```

## Global constraints¶

It is possible to specify a set of constraints that apply to every subtask, via the `Constraints()` method. For example, we can extract common constraints in the above example as follows:

```void Constraints() {
CONS(1 <= N && N <= 100);
CONS(1 <= K && K <= 100);
}

Points(20);

CONS(N == 1);
}

Points(20);

CONS(K == 1);
}