Given an array **arr[]** and an integer **M**, the task is to find the length of the longest subsequence whose sum is divisible by **M**. If there is no such sub-sequence then print **0**.

**Examples:**

Input:arr[] = {3, 2, 2, 1}, M = 3

Output:3

Longest sub-sequence whose sum is

divisible by 3 is {3, 2, 1}

Input:arr[] = {2, 2}, M = 3

Output:0

**Approach:** A simple way to solve this will be to generate all the possible sub-sequences and then find the largest among them divisible whose sum is divisible by **M**. However, for smaller values of **M**, a dynamic programming based approach can be used.

Let’s look at the recurrence relation first.

dp[i][curr_mod] = max(dp[i + 1][curr_mod], dp[i + 1][(curr_mod + arr[i]) % m] + 1)

Let’s understand the states of DP now. Here, **dp[i][curr_mod]** stores the longest subsequence of subarray **arr[i…N-1]** such that the sum of this subsequence and **curr_mod** is divisible by **M**. At each step, either index **i** can be chosen updating **curr_mod** or it can be ignored.

Also, note that only **SUM % m** needs to be stored instead of the entire sum as this information is sufficient to complete the states of DP.

Below is the implementation of the above approach:

## C++

`// C++ implementation of the approach ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` `#define maxN 20 ` `#define maxM 64 ` ` ` `// To store the states of DP ` `int` `dp[maxN][maxM]; ` `bool` `v[maxN][maxM]; ` ` ` `// Function to return the length ` `// of the longest subsequence ` `// whose sum is divisible by m ` `int` `findLen(` `int` `* arr, ` `int` `i, ` `int` `curr, ` ` ` `int` `n, ` `int` `m) ` `{ ` ` ` `// Base case ` ` ` `if` `(i == n) { ` ` ` `if` `(!curr) ` ` ` `return` `0; ` ` ` `else` ` ` `return` `-1; ` ` ` `} ` ` ` ` ` `// If the state has been solved before ` ` ` `// return the value of the state ` ` ` `if` `(v[i][curr]) ` ` ` `return` `dp[i][curr]; ` ` ` ` ` `// Setting the state as solved ` ` ` `v[i][curr] = 1; ` ` ` ` ` `// Recurrence relation ` ` ` `int` `l = findLen(arr, i + 1, curr, n, m); ` ` ` `int` `r = findLen(arr, i + 1, ` ` ` `(curr + arr[i]) % m, n, m); ` ` ` `dp[i][curr] = l; ` ` ` `if` `(r != -1) ` ` ` `dp[i][curr] = max(dp[i][curr], r + 1); ` ` ` `return` `dp[i][curr]; ` `} ` ` ` `// Driver code ` `int` `main() ` `{ ` ` ` `int` `arr[] = { 3, 2, 2, 1 }; ` ` ` `int` `n = ` `sizeof` `(arr) / ` `sizeof` `(` `int` `); ` ` ` `int` `m = 3; ` ` ` ` ` `cout << findLen(arr, 0, 0, n, m); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Java

`// Java implementation of the approach ` `class` `GFG ` `{ ` ` ` `static` `int` `maxN = ` `20` `; ` `static` `int` `maxM = ` `64` `; ` ` ` `// To store the states of DP ` `static` `int` `[][]dp = ` `new` `int` `[maxN][maxM]; ` `static` `boolean` `[][]v = ` `new` `boolean` `[maxN][maxM]; ` ` ` `// Function to return the length ` `// of the longest subsequence ` `// whose sum is divisible by m ` `static` `int` `findLen(` `int` `[] arr, ` `int` `i, ` ` ` `int` `curr, ` `int` `n, ` `int` `m) ` `{ ` ` ` `// Base case ` ` ` `if` `(i == n) ` ` ` `{ ` ` ` `if` `(curr == ` `0` `) ` ` ` `return` `0` `; ` ` ` `else` ` ` `return` `-` `1` `; ` ` ` `} ` ` ` ` ` `// If the state has been solved before ` ` ` `// return the value of the state ` ` ` `if` `(v[i][curr]) ` ` ` `return` `dp[i][curr]; ` ` ` ` ` `// Setting the state as solved ` ` ` `v[i][curr] = ` `true` `; ` ` ` ` ` `// Recurrence relation ` ` ` `int` `l = findLen(arr, i + ` `1` `, curr, n, m); ` ` ` `int` `r = findLen(arr, i + ` `1` `, ` ` ` `(curr + arr[i]) % m, n, m); ` ` ` `dp[i][curr] = l; ` ` ` `if` `(r != -` `1` `) ` ` ` `dp[i][curr] = Math.max(dp[i][curr], r + ` `1` `); ` ` ` `return` `dp[i][curr]; ` `} ` ` ` `// Driver code ` `public` `static` `void` `main(String []args) ` `{ ` ` ` `int` `arr[] = { ` `3` `, ` `2` `, ` `2` `, ` `1` `}; ` ` ` `int` `n = arr.length; ` ` ` `int` `m = ` `3` `; ` ` ` ` ` `System.out.println(findLen(arr, ` `0` `, ` `0` `, n, m)); ` `} ` `} ` ` ` `// This code is contributed by 29AjayKumar ` |

*chevron_right*

*filter_none*

## Python3

`# Python3 implementation of the approach ` `import` `numpy as np ` ` ` `maxN ` `=` `20` `maxM ` `=` `64` ` ` `# To store the states of DP ` `dp ` `=` `np.zeros((maxN, maxM)); ` `v ` `=` `np.zeros((maxN, maxM)); ` ` ` `# Function to return the length ` `# of the longest subsequence ` `# whose sum is divisible by m ` `def` `findLen(arr, i, curr, n, m) : ` ` ` ` ` `# Base case ` ` ` `if` `(i ` `=` `=` `n) : ` ` ` `if` `(` `not` `curr) : ` ` ` `return` `0` `; ` ` ` `else` `: ` ` ` `return` `-` `1` `; ` ` ` ` ` `# If the state has been solved before ` ` ` `# return the value of the state ` ` ` `if` `(v[i][curr]) : ` ` ` `return` `dp[i][curr]; ` ` ` ` ` `# Setting the state as solved ` ` ` `v[i][curr] ` `=` `1` `; ` ` ` ` ` `# Recurrence relation ` ` ` `l ` `=` `findLen(arr, i ` `+` `1` `, curr, n, m); ` ` ` `r ` `=` `findLen(arr, i ` `+` `1` `, ` ` ` `(curr ` `+` `arr[i]) ` `%` `m, n, m); ` ` ` ` ` `dp[i][curr] ` `=` `l; ` ` ` `if` `(r !` `=` `-` `1` `) : ` ` ` `dp[i][curr] ` `=` `max` `(dp[i][curr], r ` `+` `1` `); ` ` ` ` ` `return` `dp[i][curr]; ` ` ` `# Driver code ` `if` `__name__ ` `=` `=` `"__main__"` `: ` ` ` ` ` `arr ` `=` `[ ` `3` `, ` `2` `, ` `2` `, ` `1` `]; ` ` ` `n ` `=` `len` `(arr); ` ` ` `m ` `=` `3` `; ` ` ` ` ` `print` `(findLen(arr, ` `0` `, ` `0` `, n, m)); ` ` ` `# This code is contributed by AnkitRai ` |

*chevron_right*

*filter_none*

## C#

`// C# implementation of the approach ` `using` `System; ` ` ` `class` `GFG ` `{ ` ` ` `static` `int` `maxN = 20; ` `static` `int` `maxM = 64; ` ` ` `// To store the states of DP ` `static` `int` `[,]dp = ` `new` `int` `[maxN, maxM]; ` `static` `Boolean [,]v = ` `new` `Boolean[maxN, maxM]; ` ` ` `// Function to return the length ` `// of the longest subsequence ` `// whose sum is divisible by m ` `static` `int` `findLen(` `int` `[] arr, ` `int` `i, ` ` ` `int` `curr, ` `int` `n, ` `int` `m) ` `{ ` ` ` `// Base case ` ` ` `if` `(i == n) ` ` ` `{ ` ` ` `if` `(curr == 0) ` ` ` `return` `0; ` ` ` `else` ` ` `return` `-1; ` ` ` `} ` ` ` ` ` `// If the state has been solved before ` ` ` `// return the value of the state ` ` ` `if` `(v[i, curr]) ` ` ` `return` `dp[i, curr]; ` ` ` ` ` `// Setting the state as solved ` ` ` `v[i, curr] = ` `true` `; ` ` ` ` ` `// Recurrence relation ` ` ` `int` `l = findLen(arr, i + 1, curr, n, m); ` ` ` `int` `r = findLen(arr, i + 1, ` ` ` `(curr + arr[i]) % m, n, m); ` ` ` `dp[i, curr] = l; ` ` ` `if` `(r != -1) ` ` ` `dp[i, curr] = Math.Max(dp[i, curr], r + 1); ` ` ` `return` `dp[i, curr]; ` `} ` ` ` `// Driver code ` `public` `static` `void` `Main(String []args) ` `{ ` ` ` `int` `[]arr = { 3, 2, 2, 1 }; ` ` ` `int` `n = arr.Length; ` ` ` `int` `m = 3; ` ` ` ` ` `Console.WriteLine(findLen(arr, 0, 0, n, m)); ` `} ` `} ` ` ` `// This code is contributed by 29AjayKumar ` |

*chevron_right*

*filter_none*

**Output:**

3

**Time Complexity:** O(N * M)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready.