import java.util.Scanner;

/**
 * HJ16 购物单
 */
public class HJ016 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] s = sc.nextLine().split(" ");
        int money = Integer.parseInt(s[0]);
        int amount = Integer.parseInt(s[1]);
        Item[][] items = new Item[amount + 1][3];
        for (int i = 1; i <= amount; i++) {
            // i从1开始,因为主件的编号从1开始
            s = sc.nextLine().split(" ");
            int price = Integer.parseInt(s[0]);// 价格
            int flag = Integer.parseInt(s[1]);// 重要度
            int masterID = Integer.parseInt(s[2]);// 编号
            int weight = price * flag;// 权重: 价格与重要度的乘积
            Item tmp = new Item(price, weight);
            if (masterID == 0) {
                // 为主件时
                items[i][0] = tmp;
            } else {
                // 为附件时
                if (items[masterID][1] == null) {
                    items[masterID][1] = tmp;
                } else {
                    items[masterID][2] = tmp;
                }
            }
        }
        /*
            经过以上循环后,items[][] 里存放了所有的主件和附件,其中,当items[n][0]为null时,
            代表items[n]为附件.
        */

        /*
           buyable[n]: 当拥有n元钱的时候能买到的最大权重。
           此处用一维数组保存,是对算法的空间复杂度进行了优化,如用二维数组,则空间复杂度为 N * M
           但是一维数组的缺点就是,到最后不知道买了啥,哈哈。
           如下面的两个循环所示,算法的时间复杂度为N * M
        */
        int[] buyable = new int[money + 1];
        for (int i = 1; i <= amount; i++) {
            if (items[i][0] == null) {
                // 不考虑附件,因为不存在单独购买附件的情况
                continue;
            }
            for (int j = money; j >= 0; j--) {
                /*
                    定义:items[i] 为items[1][0-2], items[2][0-2]....到items[i][0-2]所包含的物品
                    此处循环是找出当拥有j元时,能从items[i]中买到的最大权重.
                    例如i = 3;j = 1000时,
                    代表了拥有1000元,从items[1][0-2], items[2][0-2], items[3][0-2]中,
                    能买到的最大权重.
                */
                // 主件
                Item master = items[i][0];
                // 情形1: 不买主件
                int max = buyable[j];
                // 情形2: 购买主件
                if (j >= master.price && max < buyable[j - master.price] + master.weight) {
                    // buyable[j - master.price]: 当用钱买下主件后剩余的钱,能买到的最大权重
                    max = buyable[j - master.price] + master.weight;
                }
                // 情形3:购买主件和附件1(附件1存在即代表主件存在)
                if (items[i][1] != null) {
                    int cost = master.price + items[i][1].price; //买下主件和附件1所需的价格
                    int weight = master.weight + items[i][1].weight;
                    if (j >= cost && max < buyable[j - cost] + weight) {
                        max = buyable[j - cost] + weight;
                    }
                }
                if (items[i][2] != null) { // 附件2存在即代表主件及附件1存在)
                    // 情形4: 购买主件及附件2
                    int cost = master.price + items[i][2].price;
                    int weight = master.weight + items[i][2].weight;
                    if (j >= cost && max < buyable[j - cost] + weight) {
                        max = buyable[j - cost] + weight;
                    }
                    // 情形5:购买主件,附件1及附件2
                    cost = master.price + items[i][1].price + items[i][2].price;
                    weight = master.weight + items[i][1].weight + items[i][2].weight;
                    if (j >= cost && max < buyable[j - cost] + weight) {
                        max = buyable[j - cost] + weight;
                    }
                }
                // 存储结果
                buyable[j] = max;
            }
        }
        System.out.println(buyable[money]);
    }

}

class Item {
    int price;// 价格
    int weight;// 权重

    public Item(int price, int weight) {
        this.price = price;
        this.weight = weight;
    }
}